I would be grateful for assistance with the following question. I would like to evaluate one or more data series with Xunit. For this I have programmed a simple example. Read the data series 10,20,30,40,80 and add 1 with a working method testAddValue.
public class TestDataRow
{
[Theory]
[MemberData(nameof(DataRowValue))]
[MemberData(nameof(ExpectedDataRowValue))]
public void TestDataRow_Method(List<int> TestValue, List<int> ExpectedValue)
{
// Init Method
Method testAddValue = new Method();
// Loop
for (int i = 0; i < TestValue.Count; i++)
{
var actual = testAddValue.TestDataRow_AddValue(TestValue[i], 1);
Assert.Equal(TestValue[i], ExpectedValue[i]);
}
}
public static IEnumerable<object[]> DataRowValue()
{
var testRow = new List<List<int>>
{
// TestValue
new List<int>{ 10, 20, 30, 40, 80},
};
yield return new object[] { testRow };
}
public static IEnumerable<object[]> ExpectedDataRowValue()
{
var expectedtestRow = new List<List<int>>
{
// ExpectedValue
new List<int>{ 11, 21, 31, 41, 81},
};
yield return new object[] { expectedtestRow };
}
}
The compiler gives no error message.
When I run the test with TestDataRow_Method(List TestValue), I get the message:
Object of type 'System.Collections.Generic.List1[System.Collections.Generic.List
1[System.Int32]]' cannot be converted to type 'System.Collections.Generic.List`1[System.Int32]'.
I don't understand this error message....
When I run the test with TestDataRow_Method(List TestValue, List ExpectedValue), I get the message that ExpectedValue is not present. This is surely a consequential error that should be taken care of by solving the above problem. For a better understanding of my approach, I am posting the full code.
What am I doing wrong?
First, a comment: you've assigned a value to actual
but you never use it. Instead, you assert that TestValue[i]
is equal to ExpectedValue[i]
which I hardly believe is your real intention here.
Your test method expects two arguments, so the MemberData
methods have to yield an array with two elements. The first array element would be the list of test values, the second array element would be the list of expected values. As programmed, each MemberData methods returns an array with one element (a single list), so there is nothing for the second parameter of your test method.
The MemberData are not executed in parallel, but rather sequentially one after the other, first each output from DataRowValue
is given to the test method and it is executed, then each output from ExpectedDataRowValue
. As programmed, they each only return a single list, so you effectively have two specific separate test cases here.
I think your intention might be more along these lines (since you didn't include your class Method
, I made a guess about what the method might be doing):
using System;
using System.Collections.Generic;
using Xunit;
namespace SO74067556
{
public class Method
{
public int TestDataRow_AddValue(int a, int b)
{
return a + b;
}
}
public class TestDataRow
{
[Theory]
[MemberData(nameof(TestData))]
public void TestDataRow_Method(int TestValue, int ExpectedValue)
{
// Arrange
Method testAddValue = new Method();
// Act
var actual = testAddValue.TestDataRow_AddValue(TestValue, 1);
// Assert
Assert.Equal(actual, ExpectedValue);
}
public static IEnumerable<object[]> TestData()
{
var data = new List<Tuple<int, int>>()
{
// Test values
new Tuple<int, int>(10,11),
new Tuple<int, int>(20,21),
new Tuple<int, int>(30,31),
new Tuple<int, int>(40,41),
new Tuple<int, int>(80,81)
};
foreach (Tuple<int, int> item in data)
{
yield return new object[] { item.Item1, item.Item2 };
}
}
}
}
For simple integer data like this, however, you would be better served by using InlineData:
[Theory]
//[MemberData(nameof(TestData))]
[InlineData(10, 11)]
[InlineData(20, 21)]
[InlineData(30, 31)]
[InlineData(40, 41)]
[InlineData(80, 81)]
public void TestDataRow_Method(int TestValue, int ExpectedValue)
{
// Arrange
Method testAddValue = new Method();
// Act
var actual = testAddValue.TestDataRow_AddValue(TestValue, 1);
// Assert
Assert.Equal(actual, ExpectedValue);
}
This is not only has less code, it is also easier to understand and the individual test cases show up in the Test Explorer in Visual Studio.