Monday, March 26, 2007 12:41 PM
I recently needed to create a custom list which would update a set of subscribing lists when the contents changed. For example, If my list had three items added to it then my subscribers would receive three separate events informing them of the change and the items added. The same was true when items were removed or inserted, the list was cleared, or when the value of an existing item in the list was changed. As you can probably already guess, we simply needed some 'glue code' to sync two collections in adjacent layers of our application.
For now, I'll spare the details of how I actually implemented the list since it was quite trivial but I did want to share something that I stumbled upon when writing the test suite. As I mentioned above, my list propagated events when certain actions occurred. This means that I had several events available that my listeners could subscribe to which meant that I also had to have tests to ensure my listeners could subscribe to and successfully receive the events. Enter my favorite toy of late, anonymous delegates....
[
Test]
public void ItemAddedEventHandlerTest()
{
ResponsiveList<
string> responsiveList = new
ResponsiveList<
string>();
bool handlerSuccessful =
false;
responsiveList.ItemAdded +=
delegate(
object sender,
ItemAddedEventArgs<
string> itemAddedEventArgs)
{
// If we successully receive the handler event we should
// toggle this switch occasionally
handlerSuccessful =
true;
Assert.AreEqual(Leroy, itemAddedEventArgs.Item);
};
// This should trigger the ItemAdded event
responsiveList.Add(Leroy);
Assert.IsTrue(handlerSuccessful,
"handlerSuccessful was not successfully toggled.");
}
I simply create a flag to represent if my event has been caught and initialize it to false. Then I tie an anonymous delegate to my event which simply toggles my flag to true, and ensures that the item I received was indeed the item that was added. I add an item to the collection which triggers the aforementioned event causing execution to return to the delegate. Following this, I simply check my state flag to ensure that it was set to true. Since events are invoked synchronously I don't have to worry about the possibility of a race condition occurring and my assertion checking my flag before it's set. This also saves the messy code of creating an entirely new method beside the test simply to handle the event which means that I can enclose all of the related items into one place for easier readability and maintainability.