当前位置: 首页 > 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.rkmt.cn/news/59880.html

相关文章:

  • 现今芜湖除甲醛公司排名:2025年专业机构推荐指南
  • 2025年11月企业管理咨询公司权威推荐榜:驻厂运营与降本增效前十强深度测评
  • 2025年最新上门家教老师综合实力排行,上门家教/一对一家教上门家教机构老师推荐榜单
  • 2025年北京离婚房产律所权威推荐榜单:婚姻律所/离婚事务所/婚姻专业律师团队精选
  • 2025年比较好的气体探测最新TOP厂家排名
  • 20256S及目视化管理公司推荐:6S管理目视化公司有哪些清
  • 2025年深圳离婚律师事务所权威推荐榜单:股权分割/房产分割律所/离婚房产专业律师团队精选
  • 2025年广东磁铁公司权威推荐榜单:手机磁铁/耐高温磁铁/圆形磁铁源头公司精选
  • 2025质量好服务好的门窗厂家推荐分析
  • react 和 Vue 相对于JQ在开发上有哪些优点?
  • 2025 上海品牌营销策划公司标杆:上海零际营销策划有限公司全案营销 / 产品营销 / 企业营销一体化服务指南
  • MATLAB决策树仿真代码(分类与回归)
  • 2025 年 11 月角接触球轴承厂家权威推荐榜:覆盖电主轴/超高速/光伏专用/切片机/高低噪音等全场景精密轴承优选指南
  • 1104. Sum of Number Segments (20)
  • 大概率上涨的股票2025年11月25日09:07
  • 1119. Pre- and Post-order Traversals (30)
  • 1122. Hamiltonian Cycle (25)
  • 剑指offer-41、和为S的连续正数序列
  • [论文笔记•(多智能体)]LLMs Can Simulate Standardized Patients via Agent Coevolution - 指南
  • 十载深耕一对一直播交友源码开发搭建,布谷鸟科技为您筑牢创业根基
  • 2025年热门的钢板预处理线厂家最新TOP实力排行
  • 广西一对一辅导机构口碑之选:2025南宁、柳州、桂林备受好评的补习机构
  • 小明的Spring Security入门到深入实战
  • OpenHarmony后台服务开发指南:ServiceAbility与ServiceExtensionAbility全解析 - 指南
  • 2025年比较好的光伏线缆厂家实力及用户口碑排行榜
  • 2025年评价高的高弹硬质棉厂家推荐及选择指南
  • 拒绝AI=拒绝饭碗?硅谷程序员的噩梦已经开始,我们的噩梦就在路上! - 详解
  • 2025年靠谱的拉幅定型机专用印染配件及改造用户口碑最好的厂家榜
  • 高纯气体过滤有哪些推荐?国内相关企业及产品解析
  • 2025年靠谱的包装木盒厂家推荐及采购参考