【发布时间】:2012-12-15 13:21:22
【问题描述】:
我刚开始在单元测试中使用 Moq,但遇到单元测试通过的问题 - 我认为它不应该通过。
我有两个对象,一个将数据发送到队列,另一个实现INotifier,如果发送失败,则调用它,它们看起来像这样(为简洁起见):
public class EmailNotifier : INotifier
{
public void Notify(string message)
{
// sends the notification by email
}
}
public class Despatcher
{
public void Despatch(int batchNumber, INotifier failureNotifier)
{
try
{
if (batchNumber.Equals(0)) throw new InvalidOperationException("Error message");
}
catch (InvalidOperationException ex)
{
failureNotifier.Notify(ex.ToString());
throw ex;
}
}
}
我正在对Despatcher 进行单元测试,以专门验证Notify 在提供的INotifier(我在嘲笑)失败时被调用(我故意迫使Despatcher 失败)传递一个 0 批号)。我这样设置我的模拟:
[TestMethod]
[ExpectedException(typeof(InvalidOperationException))]
public void Despatcher_notifies_on_failure()
{
var mockNotifier = new Mock<EmailNotifier>();
mockNotifier.Setup(n => n.Notify(It.IsAny<string>())).Verifiable();
var despatcher = new Despatcher();
despatcher.Despatch(0, mockNotifier.Object);
mockNotifier.Verify(n => n.Notify(It.IsAny<string>()), Times.Once());
}
这很好地通过了测试,这是预期的,因为批号为 0 会引发异常,导致 INotifier 调用 Notify(当我逐步完成测试时,一切都按预期工作)。
所以,我继续注释掉 failureNotifier.Notify(ex.ToString()) 行并再次运行测试 - 通过了吗?我不确定我是否正确设置和验证,因为我现在只使用 Moq 大约 2 个小时,但我认为我理解正确,但这让我有点失望。我希望这个测试失败,因为我特别想确保在失败的情况下调用Notify - 任何人都可以在这里看到任何明显的错误吗?提前感谢您一如既往的帮助。
【问题讨论】:
-
您是否尝试过使用 Times.Exactly(1)?
-
@FelicePollano 我没有,但只是有,它仍然可以通过。我还应该提到我已经完成了清理项目的明显工作,以确保不使用较旧的(没有注释
Notify行),并且单步执行我可以看到注释掉的版本正在正确使用。跨度> -
从我的角度来看,您的测试将通过 co,您期望出现
InvalidOperationException类型的异常并且它正在被抛出。如果您重新评论failureNotifier.Notify(ex.ToString());,您的测试应该会失败。因为那里有 Notify();方法调用没有被调用。 -
@Syneryx 这是我有点困惑的地方。我希望测试失败,除非测试中的所有内容都通过 - 据我所知,我正在测试是否引发了某个异常并且
Notify方法的调用已得到验证。
标签: c# unit-testing moq