Reputation: 2989
I want to pass an array of string to one of my XUnit test method, but when I just do the following it doesn't work (array + params mechanism)
[Theory]
[InlineData(new object[] { "2000-01-02", "2000-02-01" })]
public void TestSynchronizeMissionStaffing_PeriodNoMatch(string[] dateStrings)
I can work around the issue like this:
[Theory]
[InlineData(0, new object[] { "2000-01-02", "2000-02-01" })]
public void TestSynchronizeMissionStaffing_PeriodNoMatch(int dummy, string[] dateStrings)
But I'm hoping there something better to resolve the issue.
Can you tell me?
Upvotes: 77
Views: 60990
Reputation: 16986
For the benefit of searchers - in 2020, this is possible without params
or object
casting.
The key to getting it to play nicely seems to be to write the method signature before writing the InlineData
parts. Here's some working code:
[Theory]
[InlineData(true, "expected", new string[] { "expected", "another" })]
[InlineData(false, "nope!", new string[] { "expected", "another" })]
public async void StringCheck_WithInputs_ExpectResultsMatch(bool expectedResult, string expectedString, string[] possibleStrings)
{
bool actualResult = false;
foreach(var row in possibleStrings)
{
if(row == expectedString)
{
actualResult = true;
}
}
Assert.Equal(expectedResult, actualResult);
}
Upvotes: 55
Reputation: 9255
Use params
before the method's string[]
argument, and then you won't need to initialize a string[]
in InlineData
attribute, rather you could use a variable number of string
literals, for which the compiler doesn't complain one bit:
[Theory]
[InlineData("2000-01-02", "2000-02-01")]
public void TestSynchronizeMissionStaffing_PeriodNoMatch(params string[] dateStrings)
Upvotes: 82
Reputation: 129
I am using Xunit version 2.4.1
and with ChrisCa
's answer above. I was able to simply do this below, that way the data can be separated from the test(s).
public class NoGenTests
{
[Theory]
[MemberData(nameof(NoGenTestsData.Nos), MemberType = typeof(NoGenTestsData))]
public void NoGenTest(int size, int[] nos)
{
/*
foreach (var item in nos)
{
Console.WriteLine("Item is " + item);
}*/
Assert.Equal(size, nos.Length);
}
}
public class NoGenTestsData
{
public static object[] Nos =
{
new object[] {3, new int[] {2, 3, 5}},
new object[] {6, new int[] {2, 3, 5, 7, 11, 13}},
new object[] {7, new int[] {2, 3, 5, 7, 11, 13, 17}},
new object[] {8, new int[] {2, 3, 5, 7, 11, 13, 17, 19}},
new object[] {2, new int[] {2, 3}},
new object[] {1, new int[] {2}}
};
}
Upvotes: 0
Reputation: 1
Whenever you need to pass a string array as argument to your Test, you can use your code, just add the "params" keyword to your string array prepended to it. It works just fine.
[Theory]
[InlineData(new object[] { "2000-01-02", "2000-02-01" })]
public void TestSynchronizeMissionStaffing_PeriodNoMatch(params string[] dateStrings)
{
//Assert.[YourVerifier]();
}
Upvotes: 0
Reputation: 690
I believe it's a bug of XUnit. I've reported here:
https://github.com/xunit/xunit/issues/2456
Upvotes: 0
Reputation: 11046
You can use the ClassData
or MemberData
attributes. These allow you to specify a method which returns the data you need
The method can be in a separate class (ClassData
) or a method in the same class as the test (MemberData
)
this explains it nicely http://hamidmosalla.com/2017/02/25/xunit-theory-working-with-inlinedata-memberdata-classdata/
Upvotes: 3
Reputation: 97
This should work
[Theory]
[InlineData(new object[] { new string[] { "2000-01-02", "2000-02-01" } })]
public void TestSynchronizeMissionStaffing_PeriodNoMatch(string[] dateStrings)
When u initialize an object array like you did all elements on it is a single object, so when you trying to pass string array as parameter it passes a first element of the object array which is "2000-01-02".
Upvotes: 8