当前位置: 首页 > news >正文

xUnit Theory: Working With InlineData, MemberData, ClassData

原文 转发自: https://hamidmosalla.com/2017/02/25/xunit-theory-working-with-inlinedata-memberdata-classdata/

xUnit Theory: Working With InlineData, MemberData, ClassData

 

xUnit support two different types of unit test, Fact and Theory. We use xUnit Fact when we have some criteria that always must be met, regardless of data. For example, when we test a controller’s action to see if it’s returning the correct view. xUnit Theory on the other hand depends on set of parameters and its data, our test will pass for some set of data and not the others. We have a theory which postulate that with this set of data, this will happen. In this post, I’m going to discuss what are our options when we need to feed a theory with a set of data and see why and when to use them.

xUnit Theory With InlineData

This is a simplest form of testing our theory with data, but it has its drawbacks, which is we don’t have much flexibility, let’s see how it works first.

public class ParameterizedTests
{public bool IsOddNumber(int number){return number % 2 != 0;}[Theory][InlineData(5, 1, 3, 9)][InlineData(7, 1, 5, 3)]public void AllNumbers_AreOdd_WithInlineData(int a, int b, int c, int d){Assert.True(IsOddNumber(a));Assert.True(IsOddNumber(b));Assert.True(IsOddNumber(c));Assert.True(IsOddNumber(d));}
}

 

 

 

As you see above, we provide some values in InlineData and xUnit will create two tests and every time populates the test case arguments with what we’ve passed into InlineData. I said there are some limitation on what we can pass in InlineData attribute, look what happens when we try to pass a new instance of some object:

InlineData Attribute Doesn't Work With Complex Types

We can pass this kind of data to our theory with ClassData or MemberData.

xUnit Theory With ClassData

ClassData is another attribute that we can use with our theory, with ClassData we have more flexibility and less clutter:

 

public class TestDataGenerator : IEnumerable<object[]>
{private readonly List<object[]> _data = new List<object[]>{new object[] {5, 1, 3, 9},new object[] {7, 1, 5, 3}};public IEnumerator<object[]> GetEnumerator() => _data.GetEnumerator();IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();
}public class ParameterizedTests
{public bool IsOddNumber(int number){return number % 2 != 0;}[Theory][ClassData(typeof(TestDataGenerator))]public void AllNumbers_AreOdd_WithClassData(int a, int b, int c, int d){Assert.True(IsOddNumber(a));Assert.True(IsOddNumber(b));Assert.True(IsOddNumber(c));Assert.True(IsOddNumber(d));}
}

 

 

Here I’ve created a class that inherits from IEnumerable<object[]>, note that it has to be an object, otherwise xUnit will throws an error. Next I create a private list of object that I intend to pass to my theory and finally I implemented the GetEnumerator method with piggybacking on our list Enumerator. Now we can pass our TestDataGenerator class to ClassData attribute and the returned data form that class will populate the test case’s parameters.

xUnit Theory With MemberData

public class Person
{public string Name { get; set; }public int Age { get; set; }
}public class TestDataGenerator : IEnumerable<object[]>
{public static IEnumerable<object[]> GetNumbersFromDataGenerator(){yield return new object[] { 5, 1, 3, 9 };yield return new object[] { 7, 1, 5, 3 };}public static IEnumerable<object[]> GetPersonFromDataGenerator(){yield return new object[]{new Person {Name = "Tribbiani", Age = 56},new Person {Name = "Gotti", Age = 16},new Person {Name = "Sopranos", Age = 15},new Person {Name = "Corleone", Age = 27}};yield return new object[]{new Person {Name = "Mancini", Age = 79},new Person {Name = "Vivaldi", Age = 16},new Person {Name = "Serpico", Age = 19},new Person {Name = "Salieri", Age = 20}};}
}public class ParameterizedTests
{public bool IsOddNumber(int number){return number % 2 != 0;}public bool IsAboveFourteen(Person person){return person.Age > 14;}public static IEnumerable<object[]> GetNumbers(){yield return new object[] { 5, 1, 3, 9 };yield return new object[] { 7, 1, 5, 3 };}[Theory][MemberData(nameof(GetNumbers))]public void AllNumbers_AreOdd_WithMemberData(int a, int b, int c, int d){Assert.True(IsOddNumber(a));Assert.True(IsOddNumber(b));Assert.True(IsOddNumber(c));Assert.True(IsOddNumber(d));}[Theory][MemberData(nameof(TestDataGenerator.GetNumbersFromDataGenerator), MemberType = typeof(TestDataGenerator))]public void AllNumbers_AreOdd_WithMemberData_FromDataGenerator(int a, int b, int c, int d){Assert.True(IsOddNumber(a));Assert.True(IsOddNumber(b));Assert.True(IsOddNumber(c));Assert.True(IsOddNumber(d));}[Theory][MemberData(nameof(TestDataGenerator.GetPersonFromDataGenerator), MemberType = typeof(TestDataGenerator))]public void AllPersons_AreAbove14_WithMemberData_FromDataGenerator(Person a, Person b, Person c, Person d){Assert.True(IsAboveFourteen(a));Assert.True(IsAboveFourteen(b));Assert.True(IsAboveFourteen(c));Assert.True(IsAboveFourteen(d));}
}

 

 

 

MemberData gives us the same flexibility but without the need for a class. I’ve created an static method called GetNumbers which is local to our test class, and I passed it to AllNumbers_AreOdd_WithMemberData‘s MemberData attribute. But it doesn’t need to be a local method, we can pass a method from another class too, as I did with AllNumbers_AreOdd_WithMemberData_FromDataGenerator test case. Also you’re not limited to primitive types, I’ve generated and passed a complex object called Person to AllPersons_AreAbove14_WithMemberData_FromDataGenerator test, and this was something that we couldn’t do with InlineData attribute, but we can do with ClassData or MemberData attribute.

http://www.jsqmd.com/news/50027/

相关文章:

  • 2025年11月企业管理咨询公司权威推荐榜:驻厂运营与降本增效前十强深度测评
  • 2025年国内优秀速冻肉制品厂商综合实力排行榜TOP10
  • 现今芜湖除甲醛公司排名:2025年专业机构推荐指南
  • 2025年11月合肥市品质好的低温肉制品生产商综合推荐指南
  • 从零开始构建一个基于Gemini 3的AI智能体
  • 2025年市场可靠的清障车厂家推荐,直臂高空作业车/黄牌清障车/常奇清障车/程力清障车/清障车带吊/五十铃清障车清障车直销厂家推荐榜单
  • 2025年合肥牛羊肉供应商综合实力排行榜TOP10:专业评测与选择指南
  • 2025 年 11 月门窗展会权威推荐榜:移门/全屋定制/淋浴房/五金型材/门窗机械/木工机械/玻璃门展会全景解析与创新设计风向标
  • 2025年北京婚姻律所权威推荐榜单:离婚律所/离婚事务所/离婚房产律所团队精选
  • 2025 最新纸塑分离机厂家推荐排行榜:涵盖不干胶 / 淋膜纸 / 奶盒等多场景,权威筛选优质设备厂商
  • 2025年河南知名的伸缩门供应商综合实力排行榜
  • 2025 定制叠层母排厂家优选指南:深圳市格雷特通讯科技有限公司浸粉叠层母排定制 / 叠层母排浸粉专业解决方案
  • 2025年最新上门家教老师综合实力排行,上门家教/一对一家教上门家教机构老师推荐榜单
  • 中文乱码
  • 2025年靠谱的数据中心感烟火灾探测器行业内知名厂家排行榜
  • 020-Spring AI Alibaba DashScope Image 功能完整案例 - 指南
  • 2025年上海全铝家居定制生产商 top10 权威推荐榜单
  • 2025年北京离婚房产律所权威推荐榜单:婚姻律所/离婚事务所/婚姻专业律师团队精选
  • 2025年评价高的密植果树拉技塑钢线厂家选购指南与推荐
  • 2025金属复合板厂家哪家好:吉祥金属复合板厂家解读
  • 2025年上海全铝家居定制品牌前十强权威推荐榜单
  • 2025中山留学中介哪家好?优质机构解析
  • 2025ESD静电管的工厂测评-电感工厂实力分析
  • 2025 年 11 月中国水泵厂家权威推荐榜:涵盖管道/消防/多级/自吸/磁力/排污/真空/离心/卧式水泵,匠心制造与高效性能深度解析
  • kubernetes pod是什么?
  • 2025天然气压缩机源头工厂盘点分析
  • 2025并网柜制造厂家排名测评:行业风向尽在掌握
  • 金华门窗定制厂家哪家好?2025门窗定制出口工厂深度剖析
  • 2025年比较好的气体探测最新TOP厂家排名
  • 2025 广东专业音响厂家优选指南:广东天宏声光电科技有限公司 MYART/JBL/LYNX 进口国产演出 / KTV / 会议 / 舞台音响解决方案