jeudi 30 mars 2017

nUnit 3 C# - TestCaseSource - TestData - Testing that exceptions are thrown

In scenarios where I am testing methods that receive more complex objects, I normally use something similar to this to test the method against many test cases:

[TestFixture()]
public class DataTransmitterFactoryTests
{
    [Test, TestCaseSource(typeof(DataTransmitterFactoryTestCases), "CreateDataTransmitterFactoryTestCases")]
    public void CreateTransmitterForStateTest(bool isException, Type type, IDataConfigurationData config)
    {
        var vtf = new DataTransmitterFactory();
        if (isException)
        {
            Assert.That(() => vtf.CreateTransmitterForState(config), Throws.TypeOf(type));
        }
        else
        {
            var xmitter = vtf.CreateTransmitterForState(config);
            Assert.IsInstanceOf(type, xmitter);
        }
    }
}

I use an IEnumerable to feed the test cases into my test:

public class DataTransmitterFactoryTestCases
{
    public static IEnumerable CreateDataTransmitterFactoryTestCases
    {
        get
        {
            yield return new TestCaseData(false, typeof(DataFileTransmitter),
                FuncMocks.DataConfigurationDataMock(x =>
                {
                    x.DataState.Returns(DataState.PA);
                    x.TransmissionType.Returns(DataTransmissionType.File);
                    return x;
                })).SetName("CreateDataTransmitterFactoryTest - PA - FileTransmitter");
            yield return new TestCaseData(false, typeof(DataWebServicePostTransmitter),
                FuncMocks.DataConfigurationDataMock(x =>
                {
                    x.DataState.Returns(DataState.PA);
                    x.RunMode.Returns(DataRunMode.Production);
                    x.TransmissionType.Returns(DataTransmissionType.WebServicePost);
                    return x;
                })).SetName("CreateDataTransmitterFactoryTest - PA - WebServicePost");
            yield return new TestCaseData(true, typeof(NotImplementedException),
                FuncMocks.DataConfigurationDataMock(x =>
                {
                    x.DataState.Returns(DataState.PA);
                    x.TransmissionType.Returns(DataTransmissionType.RestWebService);
                    return x;
                })).SetName("CreateDataTransmitterFactoryTest - PA - RestWebService");
            yield return new TestCaseData(true, typeof(NotImplementedException),
                FuncMocks.DataConfigurationDataMock(x =>
                {
                    x.DataState.Returns(DataState.PA);
                    x.TransmissionType.Returns(DataTransmissionType.Unknown);
                    return x;
                })).SetName("CreateDataTransmitterFactoryTest - PA - Unknown");
        }
    }
}

However, often, I would like to include a test case that throws an Exception. In nUnit 2, it appears that you could just add .Throws(typeof(ArguementException) as an extension method, and the TestCase would look for that.

Now, it appears that nUnit 3 wants you to use "Assert.That(Func..." to test exceptions. In this case, I would have to have a separate test data source for exceptions.

My hack is to pass bool isException, Type type.. into the method and use an if statement to decide if I am using an Assert.That() or Assert.IsInstance(). This seems pretty hacky, but I have not been able to find a better way.

In this case, I am testing to make sure that the resulting factory object throws an Exception if it gets bad data from the factory. The resulting object only has an internal constructor.

Aucun commentaire:

Enregistrer un commentaire