为了模拟某些东西,您需要能够将模拟注入到您正在使用的任何东西中。有很多方法可以做到这一点,使用控制反转容器、环境上下文引导代码等。最简单的方法是构造函数注入并引导环境上下文,以便在您想要测试时获得您想要的模拟。例如:
WorklistLoader worklistLoader;
[SetUp]
public void Setup()
{
worklistLoader = new WorklistLoader(new MockQueryManager());
}
[Test]
public async Task TestWorklistLoader()
{
await worklistLoader.LoadWorklistItemsAsync();
}
这也意味着 WorklistLoader 不依赖于QueryManager
但取决于像这样的抽象IQueryManager
that MockQueryManager
将实施。
Where MockQueryManager
可能是这样的:
public class MockQueryManager : IQueryManager
{
public Task StartQueryTask() {/* TODO: */}
}
当然,您原来的 QueryManager 必须实现 IQueryManager:
public class QueryManager : IQueryManager
{
public Task StartQueryTask() {/* TODO: */}
}
现在,在测试使用 TPL 的类时,您会注意到我已经实现了一个返回任务的异步测试方法。这告诉测试运行者在认为测试方法已经执行之前等待结果。如果你只是简单地写了这样的内容:
[Test]
public async void TestWorklistLoader()
{
await worklistLoader.LoadWorklistItemsAsync();
}
跑步者将执行TestWorklistLoader
它会立即返回LoadWorklistItemsAsync
已完成并可能绕过任何断言。
Update:
如果您不使用 C# 5,那么我建议您只需等待单元测试中的任务完成即可。例如:
[Test]
public void TestWorklistLoader()
{
var task = worklistLoader.LoadWorklistItemsAsync();
if(!task.IsComplete()) task.Wait();
}