我正在寻找关于该主题的一般想法和/或链接,尽管我目前的具体动机是与使用BackgroundWorker和/或TPL的进度报告相关的UI任务。我对异步编程的经验水平一般是新手。我最了解的测试工具是NUnit和Rhino。
一些头脑风暴突破了我的头脑:
答案 0 :(得分:6)
单元测试异步代码并不是世界上最简单的事情,正如我在为Nito.Async库编写单元测试时所学到的。 :)
首先,您要定义实际要测试的内容。您是否只想测试是否执行了异步操作,还是要确保您的BGW /任务正确地同步其UI进度报告?
测试操作非常简单:只需等待操作完成,然后检查后置条件。 (但是,请注意BGW RunWorkerCompleted
将在ThreadPool
线程上引发,除非您给它一个同步上下文,如下例所示。)
测试正确的同步(例如,每段代码在正确的线程上运行)更复杂。
对于每个测试,您需要建立同步上下文。这将模拟UI同步上下文。我的Nito.Async库可能对此有所帮助;它有一个ActionThread
,它是一个单独的线程,包含适合拥有EAP组件(例如BGW)和调度任务(例如TaskScheduler.FromCurrentSynchronizationContext
)的同步上下文。
可以像这样使用(使用MSTest示例):
[TestMethod]
public void Test()
{
using (ActionThread thread = new ActionThread())
{
thread.Start();
// Anything passed to Do is executed in that ActionThread.
thread.Do(() =>
{
// Create BGW or call TaskScheduler.FromCurrentSynchronizationContext.
});
// The thread is gracefully exited at the end of the using block.
}
}
我发现Thread.CurrentThread.ManagedThreadId
和Thread.CurrentThread.IsThreadPoolThread
是检查正确同步的最简单方法。如果您的测试代码是在ActionThread.Do
内运行的,那么它应该将其进度更新(和完成通知)与ActionThread
同步。
很多Nito.Async单元测试都以这种方式使用ActionThread
,因此您可以查看各种示例。