I’ve seen some strange bugs that occur when you don’t properly unsubscribe from events. But it seems I’m always stuck when it comes to unit testing that.
Well, I use Moq for most of my mocking and there are some techniques you can use for testing that your subscribed, namely by Raise(ing) the event in a mock.
But I always struggle when trying to see if I actually unsubscribe in my code. Here is a simple sample that shows how you can do it with very little code.
Here is all the code:
- public interface IHasEvents
- {
- event EventHandler BeginRequest;
- }
- public class ClassUnderTest
- {
- internal IHasEvents ClassWithEvents { get; set; }
- public ClassUnderTest(IHasEvents classWithEvents)
- {
- ClassWithEvents = classWithEvents;
- ClassWithEvents.BeginRequest += OnBeginRequest;
- }
- public void Dispose()
- {
- // Yes… there are code analysis warnings here… But I want to keep simple.
- ClassWithEvents.BeginRequest -= OnBeginRequest;
- }
- public void OnBeginRequest(object sender, EventArgs e) { }
- }
- public class MockHasEvents : IHasEvents
- {
- public int BeginRequestSubscriberCount { get; set; }
- public event EventHandler BeginRequest
- {
- add { BeginRequestSubscriberCount++; }
- remove { BeginRequestSubscriberCount–; }
- }
- }
And here is the code that tests that the constructor subscribes and the Dispose() unsubscribes.
- [TestClass]
- public class ExampleEventMockTest
- {
- [TestMethod]
- public void Constructor_Subscribes_To_BeginRequest()
- {
- // Arrange
- var expected = 1;
- var hasEvents = new MockHasEvents();
- // Act
- var subject = new ClassUnderTest(hasEvents);
- // Assert
- var actual = hasEvents.BeginRequestSubscriberCount;
- Assert.AreEqual(expected, actual);
- //actual.Should().Be(expected); // I usually use FluentAssertions.
- }
- [TestMethod]
- public void Dispose_Unsubscribes_From_BeginRequest()
- {
- // Arrange
- var expected = 0;
- var hasEvents = new MockHasEvents();
- var subject = new ClassUnderTest(hasEvents);
- // Act
- subject.Dispose();
- // Assert
- var actual = hasEvents.BeginRequestSubscriberCount;
- Assert.AreEqual(expected, actual);
- }
- }
I hope this helps others.
Leave a Reply