c# - 在单元测试中预期失败时验证方法调用仍然通过

标签 c# unit-testing moq

我刚刚开始在我的单元测试中使用 Moq,但我遇到了单元测试通过的问题 - 我认为它不应该通过。

我有两个对象,一个将数据分派(dispatch)到队列,另一个实现 INotifier,如果分派(dispatch)器失败则调用它,它们看起来像这样(为简洁起见删减):

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 上被调用(我正在 mock )它失败了(我故意通过传递 0 批号来强制 Despatcher 失败)。我这样设置我的模拟:

[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 - 任何人都可以在这里看到任何明显的错误吗?提前感谢您一如既往的帮助。

最佳答案

您的测试永远不会进入验证部分。为什么?这条线

despatcher.Despatch(0, mockNotifier.Object);

抛出异常,由 ExpectedException 属性消耗并测试结束mockNotifier.Verify 行永远不会执行。

你想要的是两个单元测试,而不是:

  • 一个测试通知程序在异常时被调用(使用 .Verify)。请注意,您必须将 .Despatch 调用包装到 try { } catch { } 中,以便忽略该异常。
  • 其次,检查是否重新抛出异常(使用 ExpectedException)

关于c# - 在单元测试中预期失败时验证方法调用仍然通过,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14100642/

相关文章:

C#:是否与 C# 的 php ctype_digit 函数类似?

c# - ASP.NET 是否可以使用 Eval() 在服务器标记中调用方法?

c# - Quartz.net 多久加载一次触发器设置?

javascript - 如何测试依赖于先前调度调用的异步操作创建器?

javascript - 使用 RhinoMock 或 Moq 测试方法的内部结构

c# - Moq 设置 ServiceLocator

c# - 删除字符串末尾的数字 C#

java - Browser#getText() 返回空字符串

python - 对 API 包装器进行单元测试

unit-testing - 使用最小起订量 - 问题