In order to mock something, you need to be able to inject the mock into whatever you are using. There are many ways you can do this, with Inversion of Control containers, ambient context bootstrap code, etc. The easiest way is to constructor injection and bootstrap your ambient context to have the mock you want when you want to test. For example:
WorklistLoader worklistLoader; [SetUp] public void Setup() { worklistLoader = new WorklistLoader(new MockQueryManager()); } [Test] public async Task TestWorklistLoader() { await worklistLoader.LoadWorklistItemsAsync(); } This also means that WorklistLoader doesn't depend on QueryManager but depends on an abstraction like IQueryManager that MockQueryManager would implement.
Where MockQueryManager might be something like:
public class MockQueryManager : IQueryManager { public Task StartQueryTask() {/* TODO: */} } And of course your original QueryManager would have to implement IQueryManagear:
public class QueryManager : IQueryManager { public Task StartQueryTask() {/* TODO: */} } Now, in terms of testing TPL-using classes, you'll notice that I've implemented an async test method that returns a Task. This tells test runners to wait for the result before thinking the test method has executed. If you simply wrote something like:
[Test] public async void TestWorklistLoader() { await worklistLoader.LoadWorklistItemsAsync(); } The runner would execute TestWorklistLoader and it would return immediately before LoadWorklistItemsAsync completed and possibly bypass any asserts.
Update:
#Update:# IfIf you're not using C# 5, then I'd recommend simply waiting for the task to complete within the unit test. For example:
[Test] public void TestWorklistLoader() { var task = worklistLoader.LoadWorklistItemsAsync(); if(!task.IsComplete()) task.Wait(); }