You have reached the blog of Keith Elder. Thank you for visiting! Feel free to click the twitter icon to the right and follow me on twitter.

Writing Unit or Integration Tests That Rely on Events Firing

Posted by Keith Elder | Posted in .Net, C# | Posted on 22-10-2010

For the past week or so I’ve been working on wrapping the Sonic API to simplify it for developers at my company.  The API itself is pretty much a straight port from Java.  There is nothing C# about the API.  For example no enumerations, no generics, no nothing.  This means when you are using the API you see functions that take a parameter that is just an integer since there are no enumerations for example.  That wouldn’t be so bad if the code was documented in the proper C# way but it isn’t.  So, instead of having 100+ developers at work learn how Sonic works I have been coding up several scenarios that we need to support for the business. 

In my quest to wrap the Sonic API into a more C# centric approach I needed to write some tests obviously to make sure things were working.  Primarily these are integration tests as each test relies upon connecting to a Sonic dev environment. 

If you aren’t familiar with Sonic it is an enterprise messaging platform.  It does pub/sub, supports queues, fault tolerate and so on.  I think the stock market even uses Sonic to route messages so it has a proven track record. 

One of the scenarios I had to cover was I needed to send a message to a queue and then have that message pulled out of the queue on the other side, processed and acknowledged.  In order to do this there is one object that sends a message, and another object that is listening for a message(s).   But how do you write a test that waits on an event to happen?  Well, it turns out we’d done this before in other tests but I couldn’t for the life of me remember how.  So here’s how it works. 

Using an EventWaitHandle we can wait on an event to occur.  First is to create a handle.

   1: EventWaitHandle handle = new ManualResetEvent(false);

Using the handle we can tell it to WaitOne() which blocks the current thread until the WaitHandle receives a signal.

   1: handle.WaitOne();

Then inside our event we simply call handle.Set() (this is the signal). 

Putting all of this together we can write an integration test that sends a message to Sonic and then waits for that message to come through.  Obviously the Sonic piece doesn’t really matter, the important piece here is how to get a test to wait for an event.  Putting it all together it looks like this.

   1: [TestMethod]

   2: public void Can_Send_To_Queue_And_Receive_Message_From_Queue()

   3: {

   4:     EventWaitHandle handle = new ManualResetEvent(false);

   5:     SonicQueueSender sender = new SonicQueueSender(Helpers.SonicQueueArgs);

   6:     string sendMsg = "test";

   7:     sender.SendMessage(sendMsg, SonicDeliveryMode.NonPersistent);

   8:     SonicQueueReceiver consumer = new SonicQueueReceiver(Helpers.SonicQueueArgs);

   9:     string receiveMsg = "";

  10:     consumer.MessageRecieved += (mySender, args) =>

  11:         {

  12:             TextMessage txtMsg = (TextMessage)args.Message;

  13:             receiveMsg = txtMsg.getText();

  14:             handle.Set();

  15:         };

  16:     consumer.StartListener();

  17:     handle.WaitOne();

  18:     Assert.AreEqual(receiveMsg, sendMsg);

  19: }

Hope this helps someone out.

  • Thanks for this! is very nice information, cooll!!