Thursday, May 19, 2011

Thursday Quickie - Mocking Events with Moq

There are times when the code under test depends on an event being fired by a component we're mocking. You can explicitly fire a mocked object's event using the following code
            var authService = new Mock<IAuthenticationService>();
authService.Raise(m => m.LoggedIn += null, null as AuthenticationEventArgs);
You can also raise an event on the mock as part of a callback - i.e. fire the event when a method or property on the mock is triggered.
            var authService = new Mock<IAuthenticationService>();
authService.Setup(a => a.LoadUser(null, null))
.Returns(null as LoadUserOperation)
.Callback(() => authService.Raise(m => m.LoggedIn += null, null as AuthenticationEventArgs));
To call a delegate passed into a mocked handler, you just need to do exactly that - the magic is in getting the generics right
            var worker = new Mock<IWorker>();             worker.Setup(w => w.DoWork(It.IsAny<EventHandler<WorkCompletedEventArgs>>()))                   .Callback<EventHandler<WorkCompletedEventArgs>>(c => c(worker.Object, new WorkCompletedEventArgs()))                   .Verifiable();