Overview
Assuming this code:
public class MessageEventArgs : EventArgs
{
public string Message { get; set; }
}
public interface IService
{
event EventHandler<MessageEventArgs> Sent;
event EventHandler<MessageEventArgs> Received;
Task SendAsync(string message);
void Send(string message);
string Receive();
Task<string> ReceiveAsync();
}
Function Calls
In this approach, an event (Sent
) is raised when a configured function (which, in this case, is a method with no return value, Send()
) is invoked:
// ARRANGE
var mock = new Mock<IService>();
mock.Setup(p => p.Send(It.IsAny<string>()))
.Raises(e => e.Sent += null, (string msg) => new MessageEventArgs { Message = msg });
var service = mock.Object;
// Attach an event handler to the event:
service.Sent += (object sender, MessageEventArgs args) => TestContext.Progress.Writeline(args.Message);
// ACT
// Invoke the Send method:
service.Send("Hello World");
Asynchronous Function Calls
If we were using an asynchronous method instead, the configure it as follows:
mock.Setup(p => p.SendAsync(It.IsAny<string>()))
.Returns(Task.CompletedTask)
.Raises(e => e.Sent += null, (string message) => new MessageEventArgs { Message = message });
Method Calls
In this approach, an event is raised when a configured method is invoked. This approach is the same as above, except that configuration for what the
method will return is added before configuring the call to Raises()
:
var mock = new Mock<IService>();
mock.Setup(p => p.Receive())
.Returns("Hello")
.Raises(e => e.Received += null, (string msg) => new MessageEventArgs { Message = msg });
// ...
Asynchronous Method Calls
If we were using an asynchronous method instead, configure it as follows:
mock.Setup(p => p.ReceiveAsync())
.ReturnsAsync("Hello")
.Raises(e => e.Received += null, (string msg) => new MessageEventArgs { Message = msg });
Manually Raising Events
If the SUT accepts a service that exposes an event, subscribes to this event, and reacts when it is raised, we can manually raise an event as part of the Act step:
mock.Raise(p => p.Sent += null, new MessageEventArgs { Message = "Hello world" });
Verifying Events
Assume the event handler is registered/unregistered as follows:
service.Sent += MessageSent;
service.Sent -= MessageSent;
To verify registration/deregistration:
mock.VerifyAdd(p => p.Sent += It.IsAny<EventHandler<MessageEventArgs>>());
mock.VerifyRemove(p => p.Sent -= It.IsAny<EventHandler<MessageEventArgs>>());