Search code examples
c#unit-testingmstestassert

Assert in Try..Catch block is caught


Just came across some interesting behavior - Assert being caught by Catch block.

List<Decimal> consArray = new List<decimal>();
try
{
    Decimal d;
    Assert.IsTrue(Decimal.TryParse(item.Value, out d));
    consArray.Add(d);
}
catch (Exception e)
{
     Console.WriteLine(item.Value);
     Console.WriteLine(e);
}

Assert throws AssertFailedException and its caught by catch. Always thought that if Assert fails then test is failed and consecutive execution is aborted. But in that case - test moves along. If nothing wrong happens later - I get green test! In theory - is it right behavior?

Edited: I understand that maybe it is .NET restriction and how asserts are made in MsTest. Assert throws exception. Since catch - catches everything it catches assert exception. But is it right in theory or MsTest specific?


Solution

  • NUnit will do the exact same thing. As should any other test framework I think, but I only know MStest and NUnit in C#.

    I'd expect that your test code would not contain Decimal.TryParse, but your business logic would do that, which you'd test with an object and a method call.

    Something like:

    var sut = new Sut();
    var d = sut.DoSomethingThatReturnsTheDecimal(item.Value);
    
    Assert.AreEqual(0.123, d, string.Format("passed value can not be parsed to decimal ({0})", item.Value);
    

    In order to stay a bit closer to your implementation:

    List<Decimal> consArray = new List<decimal>();
    
    Decimal d = Decimal.MinValue;
    
    // You don't need to try-catch a Decimal.TryParse
    // Decimal.TryParse(item.Value, out d));
    
    try
    {
        d = Decimal.Parse(item.Value)
    }
    catch
    {
        // Handle exception
    }
    
    Assert.AreEqual(0.123, d);
    
    // Does the list add anything at all? In this sample it seems a bit redundant
    consArray.Add(d);
    

    Anyway, to answer your question. The try-catch is supposed to catch your AssertFailedException.

    PS: Catching the AsserFailedException and re-throwing it will also work, but it feels a bit strange to me. I'd strive to leave the Asserts outside any try-catch blocks. But that might be just my opinion which you didn't ask for :).