2

我刚刚开始在我的单元测试中使用 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正在调用它(我故意通过传递 0 批号来强制失败)。我这样设置我的模拟:INotifierDespatcher

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

4

1 回答 1

7

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

despatcher.Despatch(0, mockNotifier.Object);

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

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

  • 一项测试在异常时调用通知程序(使用.Verify)。请注意,您必须将.Despatch调用包装到try { } catch { }中,以便忽略该异常。
  • 其次,检查是否重新抛出异常(使用ExpectedException
于 2012-12-31T11:26:59.780 回答