Russell Giddings Russell Giddings - 23 days ago 11
C# Question

NUnit TestCase with Generics

Is there any way to pass generic types using a TestCase to a test in NUnit?

This is what I would like to do but the syntax is not correct...

[Test]
[TestCase<IMyInterface, MyConcreteClass>]
public void MyMethod_GenericCall_MakesGenericCall<TInterface, TConcreteClass>()
{
// Arrange

// Act
var response = MyClassUnderTest.MyMethod<TInterface>();

// Assert
Assert.IsInstanceOf<TConcreteClass>(response);
}


Or if not, what is the best way to achieve the same functionality (obviously I'll have multiple TestCases in the real code)?

Update with another example...

Here is another example with a single generic type passed...

[Test]
[TestCase<MyClass>("Some response")]
public void MyMethod_GenericCall_MakesGenericCall<T>(string expectedResponse)
{
// Arrange

// Act
var response = MyClassUnderTest.MyMethod<T>();

// Assert
Assert.AreEqual(expectedResponse, response);
}

Answer

I had occasion to do something similar today, and wasn't happy with using reflection.

I decided to leverage [TestCaseSource] instead by delegating the test logic as a test context to a generic testing class, pinned on a non-generic interface, and called the interface from individual tests (my real tests have many more methods in the interface, and use AutoFixture to set up the context):

class Sut<T>
{
    public string ReverseName()
    {
        return new string(typeof(T).Name.Reverse().ToArray());
    }
}

[TestFixture]
class TestingGenerics
{
    public IEnumerable<ITester> TestCases()
    {
        yield return new Tester<string> { Expectation = "gnirtS"};
        yield return new Tester<int> { Expectation = "23tnI" };
        yield return new Tester<List<string>> { Expectation = "1`tsiL" };
    }

    [TestCaseSource("TestCases")]
    public void TestReverse(ITester tester)
    {
        tester.TestReverse();
    }

    public interface ITester
    {
        void TestReverse();
    }

    public class Tester<T> : ITester
    {
        private Sut<T> _sut;

        public string Expectation { get; set; }

        public Tester()
        {
            _sut=new Sut<T>();
        }

        public void TestReverse()
        {
            Assert.AreEqual(Expectation,_sut.ReverseName());
        }

    }
}