How could I allow Assert in Unit Test with [ExpectedException(typeof(ArgumentException))]?

614 views Asked by At

I found, that simple Unit test

    [TestMethod()]
    [ExpectedException(typeof(ArgumentException))]
    public void UT_UU()
    {
    }

gives fault with

Message: Test method did not throw expected exception System.ArgumentException.

I successfully use [ExpetedException] to test error message output, however, any checking with Assert of side variables in the Unit Test gives it faulted.

Could I somehow decorate my test to avoid it? Or it is "political error"?

2

There are 2 answers

0
Rahul On BEST ANSWER

with [ExpectedException(typeof(ArgumentException))] your unit test will pass only when the method under test generates an exception of similar type you specified. In your case ArgumentException else it will fail with the message you have posted.

So essentially, you will have to fail your test method with that injection by means of injecting that exception. Currently your test method doesn't throw the expected exception (it actually doesn't perform anything)

For example below test method would pass

[TestMethod()]
[ExpectedException(typeof(ArgumentException))]
public void UT_UU()
{
   throw new ArgumentException();
}
1
Kyle Burns On

Using Assert statements in the body of the test that is decorated with ExpectedException doesn't really fit the pattern well if your test is isolated enough to only be testing one thing. If you follow the "Arrange, Act, Assert" pattern, then Assert is in this case handled by the ExpectedExceptionAttribute itself and the last line of code in the body of the test itself would be the "Act" because it should cause the exception to occur. If you need to know something more specific about the thrown exception to ensure that the system is meeting behavioral expectations, then I would use a try/catch within the test itself to be able to provide more granular inspection:

[TestMethod]
public void UT_UU()
{
    // Arrange
    var subject = new Foo();
    try
    {
        // Act
        subject.Bar();
    }
    catch(ArgumentException ae)
    {
        Assert.AreEqual("my message", ae.Message);
        return;
    }
    catch(Exception e)
    {
        Assert.Fail("Thrown exception was of wrong type"); // would provide more detail here
    }
    Assert.Fail("exception should have been thrown");
}

Obviously just using ExpectedException is nice because it lets you right a very clean test without extra noise. Alternatively, if you were going to re-use this type of test you could write a derivative of ExpectedException that lets you specify other characteristics (like Message) to check instead of just the type.