Try..Catch块中的断言被捕获

时间:2013-02-15 06:20:52

标签: c# unit-testing mstest assert

刚刚遇到一些有趣的行为 - AssertCatch阻止。

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);
}

断言AssertFailedException并由catch捕获。一直认为如果Assert失败,那么测试失败并且连续执行被中止。但在那种情况下 - 测试继续进行。如果以后没有发生任何错误 - 我会进行绿色测试!从理论上讲 - 这是正确的行为吗?

编辑:我明白可能是.NET限制以及如何在MsTest中进行断言。断言抛出异常。因为catch - 捕获了它所捕获的一切断言异常。但理论上是正确的还是具体的MsTest?

3 个答案:

答案 0 :(得分:6)

正如已经回答的那样,这是正确的行为。您可以通过捕获AssertFailedException并重新抛出它来更改代码以获取您的预期行为。

        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);
        }

答案 1 :(得分:5)

您的代码按预期工作。当Assert失败时,它会抛出AssertFailedException 继承自Exception。因此,您可以添加try-catch并抓住它。

在您的情况下,在throw的末尾添加catch并重新抛出异常。

答案 2 :(得分:4)

NUnit会做同样的事情。正如我认为的任何其他测试框架一样,但我只知道C#中的MStestNUnit

我希望您的测试代码不会包含Decimal.TryParse,但您的业务逻辑会执行此操作,您可以使用对象和方法调用进行测试。

类似的东西:

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);

为了更接近您的实施:

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);

无论如何,要回答你的问题。 try-catch应该会抓住你的AssertFailedException

PS:抓住AsserFailedException并重新投掷它也会有效,但对我来说感觉有点奇怪。我努力将Assert放在任何try-catch块之外。但这可能只是我的意见,你没有要求:)。