AutoFixture.NUnit?[issue #4228]

Dec 23, 2011 at 4:47 PM
Edited Dec 23, 2011 at 4:55 PM

At NUnit, the name as TheoryAttribute is TestCaseAttriute. From this attribute, we can generate auto data to parameters of a test method with the following way.

The most difficult point is to get MethodInfo of a test method from initialization of TestCaseAttriute. My solution to get the MothodInfo is to pass the type of test fixture and a method name to the TestCaseWithAutoFixtureAttriute, which is overrided from TestCaseAttriute, but at every test case, hard-coding the type and name seems tedious. With the Action attributes, introduced from Nunit 2.6(Beta), I tried remove these, but couldn't, because ITestCaseAction.BeforeTestCase is called after initializing paramters of a test. (refer to http://www.nunit.org/index.php?p=actionAttributes&r=2.6).   The following is whole source of the way I thought. If anyone find a better solution, please let me know.

The following code is a showcase of how to solve this issue, so it is not optimized about something like NullRefereceException etc.

 

[TestFixture]
public class Class1
{
    [TestCaseWithAutoFixture(typeof(Class1), "Test")]
    public void Test(int a, int b, string name)
    {
        Assert.AreEqual(1, a);
        Assert.AreEqual(2, b);
        Assert.IsTrue(name.StartsWith("name"));
    }
}

[AttributeUsage(AttributeTargets.Method, AllowMultiple = true, Inherited = false)]
public class TestCaseWithAutoFixtureAttribute : TestCaseAttribute
{
    public TestCaseWithAutoFixtureAttribute(Type testType, string methodName)
    {
        var fixture = new Fixture();
        var context = new SpecimenContext(fixture.Compose());
        var methodInfo = testType.GetMethod(methodName, BindingFlags.Instance | BindingFlags.Public);
        SetParameters(context, methodInfo);
    }

    private void SetParameters(SpecimenContext context, MethodInfo methodInfo)
    {
        var fieldInfo = GetType().BaseType.GetField("arguments", BindingFlags.Instance | BindingFlags.NonPublic);
        var infos = methodInfo.GetParameters();
        var arguments = new object[infos.Length];
        for (int index = 0; index < infos.Length; index++)
        {
            var parameterInfo = infos[index];
            var result = context.Resolve(parameterInfo);
            arguments[index] = result;
        }
        fieldInfo.SetValue(this, arguments);
    }
}
Coordinator
Dec 28, 2011 at 9:35 AM

Thanks for supplying this. I've heard rumors that it's somewhat more difficult to extend NUnit than it is to extend xUnit.net, but I have no personal experience with it.

However, I'll be happy to get feedback from NUnit experts about this approach.

Aug 30, 2013 at 12:31 AM
You are right it wasn't easy I have extended NUnit with AutoTestCaseAttribute that will use AutoFixture to generate arguments for the parameterised unit tests.

read about how to extent NUnit at http://gertjvr.wordpress.com/