xUnit中使用MemberData自动生成测试数据遇NotSupportedException问题求助
问题分析与解决
第一个写法的错误原因
- 测试数据与方法参数不匹配:你的
SampleData返回的object[]只包含ids一个元素,但测试方法ExampleTest需要两个参数(IEnumerable<int> ids和Error.Key expected),xUnit无法完成参数映射,导致执行失败。 - MemberData参数传递错误:你给
[MemberData]附加了Error.Key.InvalidParameters参数,但SampleData方法并没有定义接收参数的逻辑,xUnit不支持这种无对应接收逻辑的参数传递,直接抛出NotSupportedException。
正确的MemberData写法
修改SampleData,让它返回包含两个元素的object数组(对应测试方法的两个参数),然后直接引用该方法即可:
public static IEnumerable<object[]> SampleData() { // 自动生成测试数据,同时包含ids和预期错误类型 yield return new object[] { Enumerable.Range(1, 200), Error.Key.InvalidParameters }; // 可继续添加更多自动生成的测试用例 // yield return new object[] { Enumerable.Range(1, 300), Error.Key.InvalidParameters }; } [Theory] [InlineData(new int[] { }, Error.Key.EmptyList)] [InlineData(new int[] { -5 }, Error.Key.InvalidParameters)] [MemberData(nameof(SampleData))] // 无需额外传参 public void ExampleTest(IEnumerable<int> ids, Error.Key expected) { var ex = Assert.Throws<ValidationException>(() => sut.SampleValidation(ids)); Assert.Equal(expected.ToString(), ex.Key); }
第二个写法的错误原因
你尝试用值元组(IEnumerable<int>, ValidationError.Key)作为迭代器返回类型,但C#迭代器块只能返回实现IEnumerable<T>接口的类型,值元组本身不满足这个要求,因此编译器报错。如果想用强类型的测试数据,可以使用xUnit提供的TheoryData<T1, T2>类型:
public static TheoryData<IEnumerable<int>, Error.Key> CombinationData() { var data = new TheoryData<IEnumerable<int>, Error.Key>(); data.Add(Enumerable.Range(1, 200), Error.Key.InvalidParameters); return data; } // 使用时直接引用 [MemberData(nameof(CombinationData))]
可选:带参数的MemberData
如果需要根据不同参数生成不同测试数据,可以给SampleData添加参数,然后在[MemberData]中传递:
public static IEnumerable<object[]> SampleData(Error.Key expectedError) { // 根据传入的预期错误类型生成对应数据 yield return new object[] { Enumerable.Range(1, 200), expectedError }; yield return new object[] { Enumerable.Range(100, 200), expectedError }; } // 调用时传递参数 [MemberData(nameof(SampleData), parameters: new object[] { Error.Key.InvalidParameters })]
内容的提问来源于stack exchange,提问作者dafie
相关产品推荐
相关产品推荐

