最小起订量验证异常被抛出

本文关键字:异常 验证 | 更新日期: 2023-09-27 18:09:30

我使用最小起订量框架进行测试。我有一个场景,我希望抛出一个错误异常。我如何验证它是被抛出的?

public void Koko(List<string?> list) 
{ 
   foreach(string? str in list) 
   { 
        if (str != null) someProperty.Foo(str); 
        else throw new FormatException(); 
   } 
} 

最小起订量验证异常被抛出

如果你想验证一个异常被抛出(由你自己的代码),那么Moq不是你选择的工具。只需使用一个可用的单元测试框架。

Xunit/NUnit:

Assert.Throws<SomeException>(() => foo.Bar());

流利的断言:

Action act = () => foo.Bar();
act.Should().Throw<SomeException>();
               
https://fluentassertions.com/introduction

http://www.nunit.org/index.php?p=exceptionAsserts& r = 2.6.2

我可能误解了您的意图,但据我所知,没有必要对mock做任何事情来测试是否抛出了异常。

看起来你有一个类的方法Foo接受一个字符串-让我们调用这个InnerClass

public class InnerClass {
    public virtual void Foo(string str) {
         // do something with the string
    }
}

和一个包含InnerClass作为属性(someProperty)的类,该属性有一个成员Koko,该成员接受List作为参数

public class OuterClass {
    private readonly InnerClass someProperty;
    public OuterClass(InnerClass someProperty) {
        this.someProperty = someProperty;
    }
    public void Koko(List<string> list) {
         foreach (var str in list) {
              if (str != null)
                   someProperty.Foo(str);
              else
                   throw new FormatException();
          }
    } 
}

注意:我不能得到List<string?>编译-告诉我底层类型(字符串)必须不可为空。据我所知,只需要使值类型为空,引用类型隐式为空。

看起来你想测试,如果你传入一个字符串列表,其中任何一个字符串为空,抛出FormatException。

如果是这样,那么最小起订量的唯一原因就是让我们不再担心InnerClass的功能。Foo是一个方法,因此,除非我们使用严格模拟,否则我们可以只创建一个InnerClass模拟,而不需要其他设置。

有一个属性[ExpectedException],我们可以用它来标记我们的测试,以验证异常是否被抛出。

[TestMethod]
[ExpectedException(typeof(FormatException))]
public void ExceptionThrown() {
    var list = new List<string>() {
        "Abel",
        "Baker",
        null,
        "Charlie"
    };
    var outer = new OuterClass(new Mock<InnerClass>().Object);
    outer.Koko(list);
}

如果抛出FormatException,该测试将通过,否则将失败。

通过阅读这些答案,我意识到还有另一种使用NUnit的方法来做到这一点。下面的代码从异常中获取异常文本,并验证错误消息文本。

var ex = Assert.Throws<SomeException>(() => foo.Bar());
Assert.That(ex.Message, Is.EqualTo("Expected exception text");

和我不能得到装饰/属性语法工作(上面AlanT的答案)使用最新版本的NUnit -不知道为什么,但它抱怨无论我试图做什么

请阅读此Moq简介。下面是在调用DoSomething方法时设置InvalidOperationException抛出的方法:

mock.Setup(foo => foo.DoSomething()).Throws<InvalidOperationException>();

然后验证方法是否被调用。如果被调用,则抛出异常

mock.Verify(foo => foo.DoSomething());

你可以使用NUnit断言来测试抛出的异常:

Assert.That(() => testObject.methodToTest(), Throws.TypeOf<FaultException>());

一个老问题,但没有源代码实际显示解决方案是什么,所以下面是我所做的:

var correctExceptionThrown = false;
try
{
    _myClass.DoSomething(x);
}
catch (Exception ex)
{
    if (ex.Message == "Expected message")
        correctExceptionThrown = true;
}                    
Assert.IsTrue(correctExceptionThrown);

注意,您可以捕获特定类型的异常,而不是检查消息(通常更可取)。

我用下面的方法解决了这个问题。

由于异常破坏了我的测试,我将方法调用放在try-catch的Because块中。

那么我可以使用一个简单的Verify。