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

6.2k views Asked by At

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?

2

There are 2 answers

0
Anders Gustafsson On BEST ANSWER

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.

1
B Pete On

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.