28

I am trying to work with the ExpectedException attribute in a C# UnitTest, but I am having issues getting it to work with my particular Exception. Here's what I got:

NOTE: I wrapped asterisks around the line that is giving me the trouble.

    [ExpectedException(typeof(Exception))]
    public void TestSetCellContentsTwo()
    {
        // Create a new Spreadsheet instance for this test:
        SpreadSheet = new Spreadsheet();

        // If name is null then an InvalidNameException should be thrown. Assert that the correct 
        // exception was thrown.
        ReturnVal = SpreadSheet.SetCellContents(null, "String Text");
        **Assert.IsTrue(ReturnVal is InvalidNameException);**

        // If text is null then an ArgumentNullException should be thrown. Assert that the correct
        // exception was thrown.
        ReturnVal = SpreadSheet.SetCellContents("A1", (String) null);
        Assert.IsTrue(ReturnVal is ArgumentNullException);

        // If name is invalid then an InvalidNameException should be thrown. Assert that the correct 
        // exception was thrown.
        {
            ReturnVal = SpreadSheet.SetCellContents("25", "String Text");
            Assert.IsTrue(ReturnVal is InvalidNameException);

            ReturnVal = SpreadSheet.SetCellContents("2x", "String Text");
            Assert.IsTrue(ReturnVal is InvalidNameException);

            ReturnVal = SpreadSheet.SetCellContents("&", "String Text");
            Assert.IsTrue(ReturnVal is InvalidNameException);
        }
    }

I have the ExpectedException catching the base type Exception. Shouldn't this take care of it? I have tried using AttributeUsage, but it wasn't helping either. I know I can wrap it in a try/catch block, but I'd like to see if I can figure this style out.

Thanks all!

Jonathan
  • 589
  • 1
  • 13
  • 23

1 Answers1

56

It will fail unless the type of exception is exactly the type you've specified in the attribute e.g

PASS:-

    [TestMethod()]
    [ExpectedException(typeof(System.DivideByZeroException))]
    public void DivideTest()
    {
        int numerator = 4;
        int denominator = 0;
        int actual = numerator / denominator;
    }

FAIL:-

    [TestMethod()]
    [ExpectedException(typeof(System.Exception))]
    public void DivideTest()
    {
        int numerator = 4;
        int denominator = 0;
        int actual = numerator / denominator;
    }

However this will pass ...

    [TestMethod()]
    [ExpectedException(typeof(System.Exception), AllowDerivedTypes=true)]
    public void DivideTest()
    {
        int numerator = 4;
        int denominator = 0;
        int actual = numerator / denominator;
    }
Mick
  • 6,527
  • 4
  • 52
  • 67
  • Works like a charm, thanks for the explanation. Here's to some easy rep, cheers! – Jonathan Oct 01 '13 at 05:09
  • 7
    I wouldn't encourage [TestMethod()] [ExpectedException(typeof(System.Exception), AllowDerivedTypes=true)] For the same reason I wouldn't encourage ... catch(Exception ex) {.... – Mick Oct 01 '13 at 05:49
  • Don't we need a try/catch around the expected offending code to catch the expected exception? – Su Llewellyn Jun 15 '17 at 17:15
  • @SuLlewellyn catching the exception without rethrowing would cause the test to fail when the ExpectedExceptionAttribute is applied. – Mick Jun 20 '17 at 02:16