Asynchronous calls in C++ Windows Store Unit Tests
In Visual Studio 2012, we added support for the Async Test Methods in C#. You can call await inside the test method body and the unit test framework will appropriately wait for its completion.
Here is a sample test method.
public async Task TestMethod1()
AtomPubClient client = new AtomPubClient();
Uri uri = new Uri("http://blogs.msdn.com/b/mathew_aniyan/atom.aspx");
var result = await client.RetrieveFeedAsync(uri);
Assert.IsTrue(result.Items.Count > 0);
Notice how the method signature includes async Task and the method body contains a call to await client.RetrieveFeedAsync.
If you are using C++ Windows Store Unit Tests, you cannot leverage this model since the language does not have equivalent constructs as the async-await pattern in C#. Asynchronous methods ,though, are ubiquitous in Windows Store applications. This blog will describe a model by which you can test asynchronous functions in a C++ Windows Store Unit Test.
To get started, open “Tools -> Extensions and Updates” menu.
Search for and install C++ WinRT Async UnitTestLibrary.
This will install a new Project Template Unit Test Library with Async Helper (Windows Store apps) under the Visual C++ -> Windows Store node in New Project dialog.
Go ahead and create a new Project with this template and then add the following code to the Test Method.
Uri^ uri = ref new Uri("http://blogs.msdn.com/b/mathew_aniyan/atom.aspx");
AtomPubClient^ client = ref new AtomPubClient();
auto count = std::make_shared<int>(0);
AsyncHelper::RunSynced(task<SyndicationFeed^>(client->RetrieveFeedAsync(uri)).then([count] (SyndicationFeed^ feed)
*count = feed->Items->Size;
Assert::IsTrue(*count > 0);
Notice how AsyncHelper::RunSynced method is used. This will ensure that the task argument is completed before proceeding with the test method.
If you open asynchelper.h file in the solution, you can see how RunSynced is implemented. The key code snippet is
// Spin wait and exercise message pump
DWORD waitResult = STATUS_PENDING;
while(waitResult != WAIT_OBJECT_0)
waitResult = WaitForSingleObjectEx(hEvent, 0, true);
You can now go ahead and run this test. You will see that the test passes.
This solution approach was identified by the Patterns & Practices team and used in their Hilo project.
Direct link to the project template in Visual Studio Gallery – http://visualstudiogallery.msdn.microsoft.com/744fb771-756e-4801-811d-8994d82466dd
The project template is published to codeplex at http://asynccppunittestlib.codeplex.com/