簡體   English   中英

C#和Moq - 如何斷言事件沒有被提升

[英]C# and Moq - How to Assert an Event is Not Raised

我有一個應用程序,根據Sim對象的狀態引發事件。 特別是,如果Sim的狀態發生變化 - 即從PinRequired變為Accessible - 將引發OnStatus事件。 事件在新線程上通知偵聽器。

我在我的單元測試中使用Moq並且能夠斷言OnStatus是這樣引發的:

        [Test]
    public void TestOnStatusIsRaised()
    {
        Sim sim = new Sim();

        sim.OnStatus += OnStatus;

        lock (this)
        {
            sim.UpdateSimInfo(new Info("a new status"));
            Monitor.Wait(this);
        }

        Assert.IsTrue(_onStatusCalled);
    }

    private void OnStatus(SimStatus obj)
    {
        lock (this)
        {
            _onStatusCalled = true;
            Monitor.Pulse(this);
        }
    }

如您所見,使用Monitor類我可以等到事件被引發,然后繼續並斷言_onStatusCalled標志已設置為true。

當我想斷言事件沒有被提出時,我的困難就出現了。 我不能使用Monitor來等待事件不被提出,因為測試會永遠等待! 我可以在等待中添加超時,但這似乎是一個骯臟的黑客。

我嘗試過以下方法:

        [Test]
    public void TestOnStatusIsNotFired()
    {
        Sim sim = new Sim();
        sim.OnStatus += onStatus => Assert.Fail("OnStatus Was called");

        sim.UpdateSimInfo(new Info("the same status"));
    }

但它不起作用 - 在修復代碼以確保不引發事件之前,測試總是通過。 我甚至已經逐步執行代碼並觀察到Assert.Fail()拋出異常,但這不會導致測試失敗,因為我的事件在try / catch塊中引發並且捕獲了NUnit異常。

有任何想法嗎?

簡而言之,您不需要對多線程代碼進行單元測試。 您將其拆分為單線程部分並分別測試每個部分。

如果您還有NoStatus的活動怎么辦?

[Test]
public void TestOnStatusIsNotFired()
{
    Sim sim = new Sim();
    var mre = new ManualResetEvent(false);
    sim.OnStatus += onStatus => { mre.Set(); Assert.Fail("OnStatus Was called");}
    sim.NoStatus += () => { mre.Set();}

    sim.UpdateSimInfo(new Info("the same status"));
    mre.WaitOne()
}

使用類似的東西怎么樣:

mock.Verify(foo => foo.Execute("ping"), Times.Never());

您還可以驗證是否已使用以下命令調用OnStatus:

mock.Verify(foo => foo.Execute("ping"), Times.AtLeastOnce());

嘗試使用此鏈接獲取大量優秀的簡短示例: http//code.google.com/p/moq/wiki/QuickStart

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM