[英]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.