Serge Intern
Serge Intern

Reputation: 2989

Pass array of string to xunit test method

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

Answers (8)

JJJCoder
JJJCoder

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

yair
yair

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

oceano1970526
oceano1970526

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

Giovani Meza
Giovani Meza

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

Weifen Luo
Weifen Luo

Reputation: 690

I believe it's a bug of XUnit. I've reported here:

https://github.com/xunit/xunit/issues/2456

Upvotes: 0

ChrisCa
ChrisCa

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

Magzhan Kydyralin
Magzhan Kydyralin

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

robi-y
robi-y

Reputation: 1717

This is a C# params feature in which an array is expanded. so xunit fails to input it to your one argument, you can cast the array to force it, like this:

[InlineData((object)(new object[] { "2000-01-02", "2000-02-01" }))] see also here.

Upvotes: 5

Related Questions