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