MemberData 可以使用返回对象[] 的 IEnumerable 的属性或方法。
在这种情况下,您将看到每个产量的单独测试结果:
public class Tests
{
[Theory]
[MemberData("TestCases", MemberType = typeof(TestDataProvider))]
public void IsLargerTest(string testName, int a, int b)
{
Assert.True(b>a);
}
}
public class TestDataProvider
{
public static IEnumerable<object[]> TestCases()
{
yield return new object[] {"case1", 1, 2};
yield return new object[] {"case2", 2, 3};
yield return new object[] {"case3", 3, 4};
}
}
但是,只要您需要传递复杂的自定义对象,无论您有多少测试用例,测试输出窗口都只会显示一个测试。
这不是理想的行为,而且在调试哪个测试用例失败时确实非常不方便。
解决方法是创建您自己的包装器,该包装器将派生自 IXunitSerializable。
public class MemberDataSerializer<T> : IXunitSerializable
{
public T Object { get; private set; }
public MemberDataSerializer()
{
}
public MemberDataSerializer(T objectToSerialize)
{
Object = objectToSerialize;
}
public void Deserialize(IXunitSerializationInfo info)
{
Object = JsonConvert.DeserializeObject<T>(info.GetValue<string>("objValue"));
}
public void Serialize(IXunitSerializationInfo info)
{
var json = JsonConvert.SerializeObject(Object);
info.AddValue("objValue", json);
}
}
现在您可以将自定义对象作为 Xunit Theories 的参数,并且仍然可以在测试运行器窗口中将它们作为独立结果查看/调试:
public class UnitTest1
{
[Theory]
[MemberData("TestData", MemberType = typeof(TestDataProvider))]
public void Test1(string testName, MemberDataSerializer<TestData> testCase)
{
Assert.Equal(1, testCase.Object.IntProp);
}
}
public class TestDataProvider
{
public static IEnumerable<object[]> TestData()
{
yield return new object[] { "test1", new MemberDataSerializer<TestData>(new TestData { IntProp = 1, StringProp = "hello" }) };
yield return new object[] { "test2", new MemberDataSerializer<TestData>(new TestData { IntProp = 2, StringProp = "Myro" }) };
}
}
public class TestData
{
public int IntProp { get; set; }
public string StringProp { get; set; }
}
希望这会有所帮助。