How to unittest asynchronous methods in .Net?
If you have encountered this situation, you probably wrote yourself a test harness which understands the asynchronous callback and can wait on either the callback(s) or a timeout.
But like mock objects, writing such helpers objects quickly becomes tedious.
I found a generic solution to avoid most of this repetitive code. The CallbackWaiter class generates your test harness, just like mock frameworks.
You can browse the CallbackWaiter code or get the full project (including unittests and VS project files).
This solution works for any .Net language. The same approach can easily be implemented in Javascript and probably any dynamic language. I'm not sure about Java though (does it support runtime-defined methods?).
EventHandler
new MagicHandler
service.CallbackEvent += magicHandler;
service.DoAsyncWork(3); // Start the asynchronous work. Doesn't block.
int timeout = 1000;
MyEventArgs returnValue = magicHandler.Wait(timeout); // Wait for either the event or a timeout
Assert.AreEqual(3, returnValue.result); // Get the information channeled by the event.
}
The trouble is implementing the "MagicHandler" ;-)
But it turns out that it RealProxy can only emulate MarshalByRef objects. That unfortunately does not work to write a generic delegate, since the Delegate base class is not a MarshalByRef object.
After running into the same issues as Rich McColllister and Mike Woodring, including the weird CS0702 error, I ended-up using the same workarounds.
After validating that it is possible to generate dynamic methods and hook them to the generic class, I ironed out some smaller issues: match target signature, record event parameters, support value type parameters (code crashes without a boxing IL instruction), make the class thread safe and support multiple callbacks.