7월 14일
Visual Studio Unit Testing an asynchronous event callback
Problem ...
Long title ... simple problem: I am writing automated unit test cases for an asynchronous method call which returns back via an event handler (a callback).
If I had architected the method that I am calling I would have used the standard Begin/End methods to handle the asynchronous calls but I am using a pre-written source code so I need to adhere to its methodology.
Solution ...
Nonetheless, I needed a way to have a TestMethod make the asynchronous method call and then somehow get the results back from the event handler. I was not (am still not) aware of anything built-in to NUnit or Visual Studio Unit Testing to handle this
so I figured I was on my own.
I figured that all I really needed was a way to sleep the test method until the event handler is called and then signal it to continue and analyze the data returned from the event. Signal. I had heard that before when talking about Thread Synchronization ... threading ... that is what the event callback is ... duh. I need a thread signal!
Enter AutoResetEvent ...
Very fortunately for me, .NET has built-in just such a signal using a class called AutoResetEvent (System.Threading). Once I realized this, the code was frighteningly simple. One thread creates the signal object (initializing its state to un-signaled) and waits on it. The second thread sets the signal and the initial thread continues.
Here's some code:
-
using System.Threading;
-
using Microsoft.VisualStudio.TestTools.UnitTesting;
-
-
namespace MyTests
-
{
-
[TestClass]
-
public class MyTestClass
-
{
-
AutoResetEvent _TestTrigger;
-
DataType _MyData;
-
-
[TestMethod]
-
public void MyTestMethod()
-
{
-
this._TestTrigger =
new AutoResetEvent
(false);
-
MyAsyncCall();
-
this._TestTrigger.WaitOne();
-
Assert.AreEqual(...)
-
-
}
-
-
private void My_EventHandler(...)
-
{
-
this._MyData = result from event handler;
-
this._TestTrigger.Set();
-
-
}
-
-
}
-
-
}
You can make modifications to this so that the calling method does not wait indefinitely as well as other handy mods. If you come up with anything cool please drop a comment here so everyone can share in your find!