我在WinForms(.NET 4.0
)中使用任务来执行WCF
调用之类的冗长操作。应用程序已经在大量使用任务的产品中(几乎所有使用任务的方法都是void
)。
在单元测试期间,我们使用AutoResetEvent
s(在实际代码中)找出给定任务何时完成然后执行断言。
这让我觉得几乎所有AutoResetEvent
都是浪费精力。它们只是满足单元测试需求,没有别的。
我们可以在实际代码运行时同样创建一个包装器的包装器......它们应该在后台工作,如果是单元测试,它们应该是同步的。
类似于BackgroundWorker
的以下链接。
http://si-w.co.uk/blog/2009/09/11/unit-testing-code-that-uses-a-backgroundworker/
答案 0 :(得分:1)
为什么不能简单地在包装器中使用continuation来继续执行,如下所示:
var task = ...
task.ContinueWith(t => check task results here)
另外,unit tests can be marked as async
,如果它们的返回类型为Task
,那么您可以在那里使用await
,然后执行断言:
[Test]
public async Task SynchronizeTestWithRecurringOperationViaAwait()
{
var sut = new SystemUnderTest();
// Execute code to set up timer with 1 sec delay and interval.
var firstNotification = sut.StartRecurring();
// Wait that operation has finished two times.
var secondNotification = await firstNotification.GetNext();
await secondNotification.GetNext();
// Assert outcome.
Assert.AreEqual("Init Poll Poll", sut.Message);
}
另一种方法(来自同一篇文章)是使用自定义任务调度程序,在单元测试的情况下它将是同步的:
[Test]
public void TestCodeSynchronously()
{
var dts = new DeterministicTaskScheduler();
var sut = new SystemUnderTest(dts);
// Execute code to schedule first operation and return immediately.
sut.StartAsynchronousOperation();
// Execute all operations on the current thread.
dts.RunTasksUntilIdle();
// Assert outcome of the two operations.
Assert.AreEqual("Init Work1 Work2", sut.Message);
}
相同的MSDN杂志包含不错的article about best practices for async
unit testing。此外async void
仅应用作事件处理程序,所有其他方法应具有async Task
签名。