最小起订量验证异常被抛出
本文关键字:异常 验证 | 更新日期: 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。