2

ユニットテストでMoqをいじり始めたばかりですが、ユニットテストに合格するという問題があります。そうすべきではないと思います。

2つのオブジェクトがあります。1つはデータをキューにディスパッチし、もう1つ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ことを具体的に確認しています( 0バッチ番号を渡すことで意図的に失敗を強制しています)。私は次のようにモックを設定しました:NotifyINotifierDespatcher

[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行が実行されることはありません。

代わりに、2つの単体テスト必要です。

  • 通知機能が例外時に呼び出されるテストの1つ(with .Verify)。例外が無視されるように、.Despatch呼び出しをにラップする必要があることに注意してください。try { } catch { }
  • 次に、例外が再スローされることを確認します(with ExpectedException
于 2012-12-31T11:26:59.780 に答える