For one of my tests I needed the ability to be able to load JSON data taken from solr. I found the following blog entry by Andrew Lock: https://andrewlock.net/creating-a-custom-xunit-theory-test-dataattribute-to-load-data-from-json-files/ and extended what he did to make it work for Solr data.
In my version I am tightly coupling the attribute to a specific data model, as unfortunately there is not a generic version of the DataAttribute.
public class ProductListJsonFileAttribute : JsonFileDataAttribute
{
public ProductListJsonFileAttribute(string filePath)
: base(filePath)
{
}
public ProductListJsonFileAttribute(string filePath, string propertyName)
: base(filePath, propertyName)
{
}
public override IEnumerable<object[]> GetData(MethodInfo testMethod)
{
if (testMethod == null) throw new ArgumentNullException(nameof(testMethod));
// Get the absolute path to the JSON file
var path = _filePath;
if (!File.Exists(path)) throw new ArgumentException($"Could not find file at path: {path}");
// Load the file
var fileData = File.ReadAllText(_filePath);
if (string.IsNullOrEmpty(_propertyName))
{
return new List<object[]>{new object[]{ JsonConvert.DeserializeObject<List<ProductSearchResultsItem>>(fileData) } };
}
// Only use the specified property as the data
var allData = JObject.Parse(fileData);
var data = allData[_propertyName];
return new List<object[]> { new object[] { data.ToObject<List<ProductSearchResultsItem>>() } };
}
}
To use this in a test, do something like:
[Theory]
[ProductListJsonFile(@".\Resources\productdata.json", "docs")]
public void TestAttribute(List<ProductSearchResultsItem> productItems)
{
productItems.Count.Should().BeGreaterThan(0);
}
With the JSON file looking something like this:
{
"docs": [
{"ProductGroup": "Textured Saxony",
"productgroup_sc": "Textured Saxony",
"ProductInstanceID": "26605020",
"Size": "12"},
{"ProductGroup": "Textured Briton",
"productgroup_sc": "Textured Briton",
"ProductInstanceID": "26605021",
"Size": "14"},
{"ProductGroup": "Textured Flax",
"productgroup_sc": "Textured Flax",
"ProductInstanceID": "26605022",
"Size": "16"}]
}
No comments:
Post a Comment