我使用 MOQ 框架进行测试。我有一个场景,我希望抛出一个错误异常。我如何验证它是否被抛出?
public void Koko(List<string?> list)
{
foreach(string? str in list)
{
if (str != null) someProperty.Foo(str);
else throw new FormatException();
}
}
提前致谢。
我使用 MOQ 框架进行测试。我有一个场景,我希望抛出一个错误异常。我如何验证它是否被抛出?
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>();
我可能误读了您的意图,但据我所知,没有必要对模拟做任何事情来测试是否引发了异常。
看起来你有一个类,它的方法 Foo 接受一个字符串 - 让我们调用这个 InnerClass
public class InnerClass {
public virtual void Foo(string str) {
// do something with the string
}
}
和一个包含 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();
}
}
}
注意:我无法让 List<string?> 编译 - 告诉我基础类型(字符串)必须是不可为空的。AFAIK,只需要使值类型可以为空,引用类型可以隐式为空。
看起来您想测试如果您传入一个字符串列表,其中任何一个为空,则抛出 FormatException。
如果是这样,那么 MOQ 的唯一原因就是让我们不必担心 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");
而且我无法使用最新版本的 NUnit 使装饰/属性语法正常工作(上面 AlanT 的回答)——不知道为什么,但无论我尝试做什么,它都会抱怨。
您可以使用 NUnit Asserts 测试是否引发了异常:
Assert.That(() => testObject.methodToTest(), Throws.TypeOf<FaultException>());
请阅读此起订量简介。这是调用方法时设置InvalidOperationException
抛出的方法:DoSomething
mock.Setup(foo => foo.DoSomething()).Throws<InvalidOperationException>();
然后简单地验证是否调用了方法。如果它被调用,则引发异常
mock.Verify(foo => foo.DoSomething());
一个老问题,但没有源代码实际显示解决方案是什么,所以这就是我所做的:
var correctExceptionThrown = false;
try
{
_myClass.DoSomething(x);
}
catch (Exception ex)
{
if (ex.Message == "Expected message")
correctExceptionThrown = true;
}
Assert.IsTrue(correctExceptionThrown);
请注意,您可以捕获特定类型的异常(通常更可取),而不是检查消息。
好的,所以我通过以下方式解决了它。
由于异常破坏了我的测试,我将方法调用放在 try-catch 的因为块中。
然后我可以使用一个简单的验证。
感谢所有的帮助者...