Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update documentation to clarify passing parameters to test cases #4112

Closed
aaronfranke opened this issue May 5, 2022 · 4 comments · Fixed by #4114
Closed

Update documentation to clarify passing parameters to test cases #4112

aaronfranke opened this issue May 5, 2022 · 4 comments · Fixed by #4114
Labels

Comments

@aaronfranke
Copy link
Contributor

aaronfranke commented May 5, 2022

I am using NUnit 3.13.3 and NUnit3TestAdapter 4.2.1 with .NET Framework 4.7.2 and Visual Studio 2019.

I am not able to pass arrays or lists. I have the method return type set to an array/list, and so is the return value and the parameter type. When I try, I get one of these error messages:

MyMethodTest(MyType) Failed	60 ms
System.ArgumentException : Object of type 'MyType' cannot be converted to type 'MyType[]'.

MyMethodTest(MyType) Failed	60 ms
System.ArgumentException : Object of type 'MyType' cannot be converted to type 'System.Collections.Generic.List`1[MyType]'.

I also tried setting the return type to TestCaseData and wrapping in new TestCaseData(retval) but that doesn't work either. The only solution I have found is to set the return type to TestCaseData[] and wrap like this:

return new TestCaseData[] { new TestCaseData(retval) };

This issue seems to be the same as #1327 and it looks like there has been two rounds of attempted fixes but it still doesn't work.

@mikkelbu
Copy link
Member

mikkelbu commented May 5, 2022

@aaronfranke Can you provide a more complete example ?

The following gives me 4 test cases (whereof 2 fails)

    public class Tests
    {
        [TestCaseSource(nameof(GetData))]
        public void TestArrayLengthLargerThanTwo(int[] myArray)
        {
            Assert.That(myArray.Length, Is.GreaterThan(2));
        }

        public static IEnumerable<int[]> GetData()
        {
            yield return new[] { 1, 2, 3 };
            yield return new[] { 1 };
            yield return new[] { 2, 4, 6 };
            yield return new[] { 3 };
        }
    }

@aaronfranke
Copy link
Contributor Author

@mikkelbu Here are two examples that replicate the problem I'm facing:

using NUnit.Framework;

class ExampleClass
{
    public ExampleClass() { }
}

[TestFixture]
class ExampleClassTest
{
    private static ExampleClass[] ExampleTestData()
    {
        ExampleClass[] array = new ExampleClass[2];
        array[0] = new ExampleClass();
        array[1] = new ExampleClass();
        return array;
    }

    [Test]
    [TestCaseSource(nameof(ExampleTestData))]
    public void ExampleTest(ExampleClass[] data)
    {
        Assert.That(true);
    }
}
Test	Duration	Traits	Error Message
ExampleTest(ExampleClass) Failed	61 ms		System.ArgumentException : Object of type 'ExampleClass' cannot be converted to type 'ExampleClass[]'.
using NUnit.Framework;
using System.Collections.Generic;

class ExampleClass
{
    public ExampleClass() { }
}

[TestFixture]
class ExampleClassTest
{
    private static List<ExampleClass> ExampleTestData()
    {
        List<ExampleClass> list = new List<ExampleClass>();
        list.Add(new ExampleClass());
        list.Add(new ExampleClass());
        return list;
    }

    [Test]
    [TestCaseSource(nameof(ExampleTestData))]
    public void ExampleTest(List<ExampleClass> data)
    {
        Assert.That(true);
    }
}
Test	Duration	Traits	Error Message
ExampleTest(ExampleClass) Failed	90 ms		System.ArgumentException : Object of type 'ExampleClass' cannot be converted to type 'System.Collections.Generic.List`1[ExampleClass]'.

@aaronfranke
Copy link
Contributor Author

aaronfranke commented May 6, 2022

Based on your example I think I see what's wrong. NUnit is pulling out each element of the returned List and using that as test case data. The second example I posted works if I change the test data method to this:

    private static IEnumerable<List<ExampleClass>> ExampleTestData() {
        List<ExampleClass> list = new List<ExampleClass>();
        list.Add(new ExampleClass());
        list.Add(new ExampleClass());
        return new List<List<ExampleClass>> { list };
    }

The documentation for TestCaseSource needs to be updated. Currently it just says Indicates the source to be used to provide test fixture instances for a test class. and does not mention anything about the return type being an IEnumerable containing the actual data that's passed to the test method.

@mikkelbu
Copy link
Member

mikkelbu commented May 6, 2022

Documentation PRs are welcome. The online documentation specifies all the requirements https://docs.nunit.org/articles/nunit/writing-tests/attributes/testcasesource.html

The second argument is a string representing the name of the source used to provide test cases. It has the following characteristics:

  • It may be a field, property or method in the test class.
  • It must be static. This is a change from NUnit 2.x.
  • It must return an IEnumerable or a type that implements IEnumerable. For fields an array is generally used. For properties and methods, you may return an array or implement your own iterator.
  • The individual items returned by the enumerator must be compatible with the signature of the method on which the attribute appears. See the Test Case Construction section below for details.

@aaronfranke aaronfranke changed the title Cannot pass arrays or lists as single parameters in test cases Update documentation to clarify passing parameters to test cases May 10, 2022
@mikkelbu mikkelbu removed the confirm label Jul 11, 2022
@mikkelbu mikkelbu added this to the 4.0 milestone Jul 11, 2022
@OsirisTerje OsirisTerje removed this from the 4.0 milestone Nov 26, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants