If you are building a webservice consumer for your mobile C# (MonoTouch/Monodroid/W8) app you are probably using asynchronous calls.
Although this is nice for the end-user, it is more difficult to test this using Nunit or other testing frameworks since when you embed an asynchronous call in a Nunit testcase it won’t wait for the callback on itself and since there is (probably) no Assert in the calling function (it would reside in the callback function) the test results in True without actually testing anyting.
As this nice post at zong’s website indicates, you can use the ManualResetEvent class to let the main thread wait until it gets signalled. By then sending that signal from the asynchronous webservice callback, the main thread will presume execution and can handle the returned (asynchronous) result.
Keep in mind that NUnit has currently no support for asynchronous tasks in their testcases in default, as also stated in this StackOverflow answer.
In Zh0ng’s answer he uses the following to check if the webservice call reaches a timeout limit (or never happens at al) by using
if (!syncEvent.WaitOne(10000)) // Wait for the end of the asynchronous operation during 10 seconds maximum.
Assert.Fail("Timeout."); // The test fails if the operation didn't end fast enough.
If you need to call multiple asynchronous functions after eachother in your test you can easily do so by changing the previous code into:
if (syncEvent.WaitOne(YOUR_TIMEOUT_LIMIT)) // Wait for the end of the asynchronous operation during 10 seconds maximum.
secondSyncEvent = new ManualResetEvent (false);
if (!secondSyncEvent.WaitOne (WEBSERVICE_TIMEOUT))
Assert.Fail ("second callback :: Timeout.");
Assert.Fail("first callback :: Timeout."); // The test fails if the operation didn't end fast enough.
So, the important stuff is that you set the secondSyncevent and that you call it’s WaitOne function inside the previous WaitOne.
Do mind though, that this only is good practice for just a couple of calls but that there are more nice solutions when you want to call a large amount of calls (more then 3-5 calls).
The upside of the ManualResetEvent approach is that you can specifiy call-specific timeout values if you want and that you can either participate on the callback or just check if a timeout occurred.
Drop me a line about your thoughts on this as I am curious about your comments on how you do async webservice testing.