I want to upgrade from NUNIT 2.x to 3.x but i have tests like
[TestCase("12345", ExpectedResult = "SUCCESS")]
[TestCase("invalidkey", ExpectedException = typeof(ArgumentException))]
[TestCase(null, ExpectedException = typeof(ArgumentNullException))]
public string ReturnsStatus(string filePath)
{
    // Arrange
    // Act
    Tuple<string, string> result = service.Create(filePath);
    // Assert
    return result.Item1;
}
How to rewrite this kind of tests? NUNIT 3.x does not have ExpectedException, that is my refactorization reason. I dont want to split into 3 tests. Thanks.
This is an old question, but any way...
As it was mentioned, ExpectedException is considered as a bad practice, since you can't be sure what exact part of your test throws exception (in your code it can be Create(), or get_Item1()).
However, you don't need to write separate test-method for every single case. In most situations (and in your example) it's enougth to split for two tests: positive and negative. Positive case can remain unchanged. Negative case can use type of expected exception as parameter, so that:
[TestCase("",  typeof(ArgumentException))]
[TestCase(null, typeof(ArgumentNullException))]
public void ReturnStatusInvalidArgument(string filePath, Type expectedException)
{
    Assert.Throws(expectedException, () => Method(filePath));
}
Or if you prefer "ExpectedResult" style, then you can use following
    [TestCase("", ExpectedResult = typeof(ArgumentException))]
    [TestCase(null, ExpectedResult = typeof(ArgumentNullException))]
    public Type ReturnStatusInvalidArgument(string filePath)
    {
        return Assert.Catch(() => Method(filePath)).GetType();
    }
                        As you discovered, NUnit 3 removed ExpectedExceptionAttribute and the related properties on TestCaseAttribute and TestCaseData.
This was done after a lot of community discussion, with less than 100% agreement but with most people recognizing that broad detection of exceptions at the level of the entire test constitutes an anti-pattern. Your example actually represents the one case where it isn't such a bad practice: a test method with only one statement. Unfortunately, you are affected by the change as well.
Two recommendations:
Assert.Throws or Assert.That(..., Throws...) for the error test.I think "one method==one test" is best practise:
[TestCase("12345", ExpectedResult = "SUCCESS")]
public string ReturnStatusTest_SUCCESS()
{
    return ReturnsStatus("12345");
}
[TestCase("invalidkey", ExpectedException = typeof(ArgumentException))]
public string ReturnStatusTest_SUCCESS()
{
    return ReturnsStatus("invalidkey");
}
[TestCase(null, ExpectedException = typeof(ArgumentNullException))]
public string ReturnStatusTest_SUCCESS()
{
    return ReturnsStatus(null);
}
public string ReturnsStatus(string filePath)
{
    // Arrange
    // Act
    Tuple<string, string> result = service.Create(filePath);
    // Assert
    return result.Item1;
}
                        If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With