Wednesday, April 13, 2011

ExpectedException not catching exception, but I can catch it with try catch

Any ideas on this one? I'm trying to write a unit test that will delete an item and confirm that item is no longer in a repository by trying to retrieve the item by its ID which should throw a DataAccessException. However, the test keeps failing. I added a try catch block and sure enough I caught the exception I was expecting. I'm using VS Test Tools for unit testing.

    [ExpectedException(typeof(DataAccessException))]
    private static void NHibernateRepositoryBaseDeleteHelper<T, TKey>(T myItem, TKey myItemId)
    {
        MyTestRepository<T, TKey> myRepository = new MyTestRepository<T, TKey>();
        myRepository.Delete(myItem);
        myRepository.CommitChanges();
        try
        {
            myRepository.GetById(myItemId, false);
        }
        catch (DataAccessException dae)
        {
            Assert.IsTrue(true);
        }
    }
From stackoverflow
  • You need to add the ExpectedException attribute onto the same method which has the TestMethod attribute. The VS Unit Test Framework will only look for an ExpectedException attribute at the entry point of a particular test.

    [TestMethod]
    [ExpectedException(typeof(DataAccessException))]
    public void ATestMethod() {
      ...
      NHibernateRepositoryBaseDeleteHelper(itemValue, keyValue);
    }
    
  • You are munging up your delete method first of all. I would have a separate delete method and test method. Yes, you are testing the delete, but really you are testing the behavior that is associated with delete. There are probably additional tests here.

    As this is part of what appears to be an autogenerated test, I would not add to the same repository object in that test, but would perform my test(s) in their own test methods and use the delete as part of the set up for the class. That will certainly separate the test from the delete.

    Hope this helps.

  • I'll add to what Jared said by pointing out that the "ExpectedException" attribute sucks. There's no way to assert that the exception's message is correct (the "message" parameter doesn't do what you might think it does) and you can't check for multiple exceptions in one test.

    A better solution is to do something like this: http://geekswithblogs.net/sdorman/archive/2009/01/17/unit-testing-and-expected-exceptions.aspx

    That class lets you do neat stuff like this:

    [TestMethod]
    public void TestAFewObviousExceptions()
    {
    // some setup here
       ExceptionAssert.Throws("Category 47 does not exist", () => 
                    wallet.Categories.GetChildCategoryIds(47));
       ExceptionAssert.Throws("Id Flim is not valid", () => 
                    wallet.Categories.IdFromName("Flim"));
    }
    
    Scott Dorman : Have to give you a +1 for the link. :) Just curious, did you need to edit or add to the ExceptionAssert class in the blog post?
    mhenry1384 : I originally wrote in my answer "I wrote my own exception class based off that code", but now that I compare the function that I use with what's on that website, it looks like all I did was take it verbatim and stick it in my own namespace. :-)

0 comments:

Post a Comment