简体   繁体   中英

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?

As already answered, this is correct behavior. You can change your code to get Your expected behavior by catching the AssertFailedException and re-throwing it.

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

        catch (Exception e)
        {
            Console.WriteLine(item.Value);
            Console.WriteLine(e);
        }

Your code is working as expected. When an Assert fails it throws an AssertFailedException which inherits from Exception . So you can add a try-catch and catch it.

In your case, add a throw at the end of the catch and re-throw the exception.

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 Assert s outside any try-catch blocks. But that might be just my opinion which you didn't ask for :).

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM