我在.NET平臺上使用Xunit和NMock。 我正在測試一個方法是異步的表示模型。 該方法創建一個異步任務並執行它,以便該方法立即返回,並且需要檢查的狀態尚未準備好。有沒有一種方法來單元測試異步方法?
我可以在不修改SUT的情況下設置標誌,但這意味着我必須在while循環中檢查標誌,例如可能超時。
我有什麼選擇?
我在.NET平臺上使用Xunit和NMock。 我正在測試一個方法是異步的表示模型。 該方法創建一個異步任務並執行它,以便該方法立即返回,並且需要檢查的狀態尚未準備好。有沒有一種方法來單元測試異步方法?
我可以在不修改SUT的情況下設置標誌,但這意味着我必須在while循環中檢查標誌,例如可能超時。
我有什麼選擇?
您的對象是否具有異步方法完成的任何種類的信號,例如事件?如果是這樣的話,你可以用下面的辦法:
[Test]
public void CanTestAsync()
{
MyObject instance = new MyObject()
AutoResetEvent waitHandle = new AutoResetEvent(false);
// create and attach event handler for the "Finished" event
EventHandler eventHandler = delegate(object sender, EventArgs e)
{
waitHandle.Set(); // signal that the finished event was raised
}
instance.AsyncMethodFinished += eventHandler;
// call the async method
instance.CallAsyncMethod();
// Wait until the event handler is invoked
if (!waitHandle.WaitOne(5000, false))
{
Assert.Fail("Test timed out.");
}
instance.AsyncMethodFinished -= eventHandler;
Assert.AreEqual("expected", instance.ValueToCheck);
}
我的首選方法是模擬並注入實際的線程機制,以便在測試中它不是異步的。有些時候這是不可能的(如果方法的線程是框架的一部分,或者不在你的控制之下)。
如果你不能控制線程創建,那麼等待線程以某種方式完成,或者是一個while循環,或者只是一個定時的等待,無論線程應該佔用多長時間,並且如果狀態爲不在那裏,因爲反正花了太長時間。
看看我的文章單元測試Silverlight應用程序
http://www.codeproject.com/KB/silverlight/Ag3DemoLOB.aspx
有單元的實例測試調用一個方法WCF服務異步...
只是覺得你可能想要在這方面的更新,因爲#1答案實際上是建議一個較舊的模式來解決這個問題。
在.net 4.5 + xUnit 1.9或更高版本中,您可以簡單地返回一個Task,並可以使用測試中的async關鍵字讓xunit等待測試異步完成。
請參閱這篇文章xUnit.net 1.9
[Fact]
public async Task MyAsyncUnitTest()
{
// ... setup code here ...
var result = await CallMyAsyncApi(...);
// ... assertions here ...
}
.NET不具備條件變量? – jrockway 2009-07-23 21:50:29
你想要測試什麼? – 2009-07-23 22:00:08
有複雜的解決方案,但如果它只是一個測試,那麼循環/超時/標誌選項沒有任何問題。 – Ray 2009-07-24 08:19:10