ExpectedException attribute in Visual Studio 2008 and Visual Studio 2010

Today I tried to write my first unit tests under Visual Studio 2010. Just to see if Visual Studio testing system can now also be used for unit tests. Visual Studio 2008 had some annoying problems with test and I preferred to use nUnit instead. Visual Studio 2010 brings some good news – tests work. Take a look at my example.

Problems with tests under Visual Studio 2008

Visual Studio 2008 tests are problematic because they are not able to handle System.Exception as expected exception. Okay, I know the background, System.SystemException should be base class for fatal system exceptions and System.ApplicationException should be base class for non-fatal application exceptions. But this works only somewhere we don’t belong – the ideal world. Applications still throw System.Exception and also .Net Framework classes throw it.

Here is example of failing test. Notice that ExpectedException sais that System.Exception is expected when test is run.

[TestMethod]
[
ExpectedException(typeof(Exception))]
public void
ThisTestFails()
{
   
throw new Exception("This test fails!");
}

And here you can see the result.

This test fails

Test fails with error message: UTA017: TestProject1.UnitTest1.ThisTestFails has invalid ExpectedException attribute. The type must inherit from Exception. I handle this situation as bug in Visual Studio because this limitation is pointless – System.Exception is not abstract class.

Every bad thing usually has its good side too. Under these limited conditions one can avoid the amount of hack-tests low by throwing correct exceptions in his or her code. If something is null that should have value then instead of System.Exception it is good idea to throw System.ArgumentNullException etc.

Visual Studio 2008 tests hack

There are two hacks to solve this issue. First hack has same structure as code above. We just change the type of exception we expect and in test we throw exception using correct type.

[TestMethod]
[
ExpectedException(typeof(ApplicationException))]
public void
ThisTestChangesExceptionType()
{
   
try
    {
       
throw new Exception("This test passes!"
);
    }
   
catch (Exception
ex)
    {
       
throw new ApplicationException(ex.Message, ex);
    }

}

Our second hack is simpler. Instead of using ExpectedException attribute we assert the type of exception.

[TestMethod]
public void
ThisTestUsesAssert()
{
   
try
    {
       
throw new Exception("This test passes!"
);
    }
   
catch (Exception
ex)
    {
        Assert.IsTrue(ex.GetType() ==
typeof(Exception));
    }

}

Now we get nice output for these tests as shown on following screenshot.

This test pass

Both versions of this test passed well. Although these solutions are not very nice they work.

Visual Studio 2010 tests

Visual Studio 2010 handles the first test correctly. Here is the code of my test.

[TestMethod]
[
ExpectedException(typeof(Exception))]
public void
ThisTestExpectsException()
{
   
throw new Exception("Visual Studio 2010 rocks!");
}

And here is the screenshot with test result.

ExpectedException works on Visual Studio 2010

As we can see Visual Studio 2010 has this issue fixed and we can write also tests that expect System.Exception to be thrown. Happy testing!

Gunnar Peipman

Gunnar Peipman is ASP.NET, Azure and SharePoint fan, Estonian Microsoft user group leader, blogger, conference speaker, teacher, and tech maniac. Since 2008 he is Microsoft MVP specialized on ASP.NET.

    2 thoughts on “ExpectedException attribute in Visual Studio 2008 and Visual Studio 2010

    • July 25, 2009 at 4:08 pm
      Permalink

      I don’t understand. It’s not broken technically because now we can expect System.Exception to be thrown somewhere in a test.

      But it’s still broken because the paradigm of expecting an exception **somewhere** in the test is shoddy validation. Your hack #2 seems like a better way to go — more like Assert.Throws(). That way you are validating which piece of code is throwing the exception you’re looking for.

    • July 25, 2009 at 4:53 pm
      Permalink

      In VS2010 everything works as expected. But is bug on Visual Studio 2008. I cannot name it differently because there is possibility that .Net Framework or some third-party library throws System.Exception. Yes, also .Net Framework classes are able to throw System.Exception. That’s why it is weird that even .Net Framework 3.5 SP1 didn’t fixed this issue.

    Leave a Reply

    Your email address will not be published. Required fields are marked *