C# MOQ - 验证抛出异常

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/16053433/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-09 23:50:39  来源:igfitidea点击:

MOQ - verify exception was thrown

c#unit-testingmoq

提问by Gal Ziv

I working with MOQ framework for my testing. I have a scenario in which I expect a fault exception to be thrown. How can I verify it was thrown?

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

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

Thanks in advance.

提前致谢。

回答by Sergey Berezovskiy

Please read this Introduction to Moq. Here is the way to setup InvalidOperationExceptionthrowing when DoSomethingmethod is invoked:

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

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

Then simply verify if method was called. If it was called, then exception was raised

然后简单地验证是否调用了方法。如果它被调用,则引发异常

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

回答by g t

You can test that an Exception is thrown using NUnit Asserts:

您可以使用 NUnit Asserts 测试是否抛出异常:

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

回答by treze

If you want to verify an exception was thrown (by your own code) then Moq is not your tool of choice for that. Simply use one of the unit test frameworks available.

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

Xunit/NUnit:

Xunit/NUnit:

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

Fluent Assertions:

流利的断言:

Action act = () => foo.Bar();
act.ShouldThrow<SomeException>();

http://fluentassertions.codeplex.com/documentation

http://fluentassertions.codeplex.com/documentation

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

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

回答by Gal Ziv

Ok so I solved it in the following way.

好的,所以我通过以下方式解决了它。

Since the exception broke my test I put the method call in the Because block in try-catch.

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

Then I could use a simple Verify.

然后我可以使用一个简单的验证。

Thanks to all helpers...

感谢所有帮助...

回答by AlanT

I may be mis-reading your intent, but as far as I can see there is no need to do anything to a mock in order to test that the exception has been thrown.

我可能误读了您的意图,但据我所知,无需对模拟执行任何操作来测试是否已抛出异常。

It looks like you have a class with a method Foo that takes a string - lets call this InnerClass

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

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

and a class which contains an InnerClass as a property (someProperty) which has a member Koko that takes a List<string> as a parameter

以及一个包含 InnerClass 作为属性 (someProperty) 的类,该类具有一个成员 Koko,该成员将 List<string> 作为参数

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

NOTE:I cannot get List<string?> to compile - tells me that the underlying type (string) must be non-nullable. AFAIK, one only needs to make value types nullable, reference types are implicitly nullable.

注意:我无法让 List<string?> 编译 - 告诉我基础类型(字符串)必须是不可为空的。AFAIK,只需要使值类型可以为空,引用类型可以隐式为空。

It looks like you want to test that if you pass in a list of strings where any of them are null that a FormatException is thrown.

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

If so, then the only reason for a MOQ is to release us from worrying about the InnerClass functionality. Foo is a method, so, unless we are using strict mocks, we can just create an InnerClass mock with no other setup.

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

There is an attribute [ExpectedException]with which we can tag our test to verify that the exception has been thrown.

有一个属性[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);

}

This test will pass if a FormatException is thrown and fail if it is not.

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

回答by Ronnie

An old question but no source code actually showing what the solution was, so here's what I did:

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

var correctExceptionThrown = false;

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

Assert.IsTrue(correctExceptionThrown);

Note rather than checking the message, you can catch a particular type of exception (generally preferable).

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

回答by DaveN59

Reading through these answers I realized there is yet another way to do this using NUnit. The following gets the exception text from an exception and verifies the error message text.

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

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

And I couldn't get the decoration / attribute syntax to work (AlanT's answer above) using the latest version of NUnit -- not sure why, but it complained no matter what I tried to do.

而且我无法使用最新版本的 NUnit 使装饰/属性语法起作用(上面 AlanT 的回答)——不知道为什么,但无论我尝试做什么,它都会抱怨。