Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is there a way to pass delegates to a NUnit TestCase or TestFixture?

Basically I want to be able to plug-in methods to a TestCase or TestFixture in NUnit to vary the behavior. In essence I want to do this:

[TestFixture]
public class MethodTests
{
    public delegate void SimpleDelegate();

    public static void A()
    {
        // Do something meaningful
    }

    public static void B()
    {
        // Do something meaningful
    }

    public static void C()
    {
        // Do something meaningful
    }

    [TestCase(A,B,C)]
    [TestCase(C,A,B)]
    [TestCase(C,B,A)]
    public void Test(SimpleDelegate action1, SimpleDelegate action2, SimpleDelegate action3 )
    {
        action1();
        action2();
        action3();
    }
}

The errors I get back for [TestCase(A,B,C)] are

  • Error 6 Argument 1: cannot convert from 'method group' to 'object'
  • Error 7 Argument 2: cannot convert from 'method group' to 'object'
  • Error 8 Argument 3: cannot convert from 'method group' to 'object'

Do you know if there is any way to get this or something like it to work?

like image 244
Bryan Mau Avatar asked Aug 28 '13 20:08

Bryan Mau


People also ask

What is TestFixture attribute used in NUnit?

The [TestFixture] attribute denotes a class that contains unit tests. The [Test] attribute indicates a method is a test method. Save this file and execute the dotnet test command to build the tests and the class library and run the tests. The NUnit test runner contains the program entry point to run your tests.

How do you prioritize test cases in NUnit?

There is no facility in NUnit to order tests globally. Tests with an OrderAttribute argument are started before any tests without the attribute. Ordered tests are started in ascending order of the order argument. Among tests with the same order value or without the attribute, execution order is indeterminate.

How do you write multiple test cases in NUnit?

If you add a second parameter with the Values attribute, for per value of the first parameter, NUnit will add a test for every value of the second parameter. Another way to avoid having to write duplicate tests when testing the same behaviour with different inputs is to use TestCase attribute on the test itself.


2 Answers

This is where the TestCaseSourceAttribute comes to the rescue.

First, define an object array containing your list of test cases. Next, invoke the test cases by referencing to the object array as the Test's [TestCaseSource]. This should build and run as you intended.

private static readonly object[] TestCases =
{
    new SimpleDelegate[] { A, B, C },
    new SimpleDelegate[] { C, A, B },
    new SimpleDelegate[] { C, B, A }
};

[Test, TestCaseSource("TestCases")]
public void Test(SimpleDelegate action1, SimpleDelegate action2, 
                 SimpleDelegate action3)
{
    action1();
    action2();
    action3();
}

If you need a more complex argument list, you could for example use Tuple instead of SimpleDelegate[] to create strongly typed argument lists.

like image 76
Anders Gustafsson Avatar answered Sep 18 '22 05:09

Anders Gustafsson


Building on Anders' fine answer:

You could use the NUnit TestCaseData type instead of the array of Delegates.

This has a couple of advantages. First, you can pass parameters of multiple types to the test method. (Not needed in this case, but it was helpful in my case.) Second, you can add further properties to the TestCaseData object. In my case, I used .SetName to add a name to each test case so the NUnit GUI clearly identifies the test case that is running. To modify Anders' example:

private static readonly object[] TestCases =
{
    new TestCaseData( A, B, C ).SetName("A B C"),
    new TestCaseData( C, A, B ).SetName("C A B"),
    new TestCaseData( C, B, A ).SetName("C B A")
};

[Test, TestCaseSource("TestCases")]
public void Test(SimpleDelegate action1, SimpleDelegate action2, SimpleDelegate action3)
{
    action1();
    action2();
    action3();
}

As Anders mentions, one can use Tuples to support a more complex argument list; but my project is in .Net 3.5 which does not support Tuples.

like image 32
B Pete Avatar answered Sep 21 '22 05:09

B Pete