Search code examples
.netunit-testingeventsmoqeventhandler

Mocking Event handling will not cover delegate function assigned


Trying to mock an EventHandler for an Event raised from another class. However, when I run the test, the test does not cover the code that implemented inside the handler.

Test

[Fact]
public void ShouldConsumeFromTopicAndRaiseEvent()
{
    ConsumerEventMessage message = new ConsumerEventMessage()
    {
        Message = "Test"
    };
    
    _consumerHandlerMock.Setup(_ =>
        _.Consume(It.IsAny<string>(),
            It.IsAny<CancellationToken>()));
    _consumerHandlerMock.Raise(_ => 
        _.HandleConsumeMessageEvent += null, message);
    _consumerHandlerMock.Object.HandleConsumeMessageEvent += (sender, eventMessage) =>
    {
        FetchNotificationDataByApplicationIdMessage notificationDataByApplicationIdMessage =
            new FetchNotificationDataByApplicationIdMessage()
            {
                ApplicationId = eventMessage.Message
            };
        _fetchNotificationDataByApplicationIdEventMock.Raise(_ =>
            _.FetchNotificationDataByApplicationIdEvent += null, notificationDataByApplicationIdMessage);
    };
    
   Task result = _fetchNotificationDataByApplicationIdConsumer
        .StartAsync(It.IsAny<CancellationToken>());
   result.Wait();
   result.Should().Be(Task.CompletedTask);
}

Implementation

private void SubscribeToEvent(CancellationToken cancellationToken)
{
    _consumerHandler.HandleConsumeMessageEvent += (sender, message) =>
    {
        FetchNotificationDataByApplicationIdMessage fetchNotificationDataByApplicationId = 
            new FetchNotificationDataByApplicationIdMessage()
        {
            ApplicationId = message.Message
        };
        FetchNotificationDataByApplicationIdEvent(this, fetchNotificationDataByApplicationId);
    };
    _consumerHandler.Consume(_topic, cancellationToken);
}

Solution

  • The setup was done incorrectly.

    Reference: MOQ Quickstart: Events

    [Fact]
    public async Task ShouldConsumeFromTopicAndRaiseEvent() {
        // Arrange
        ConsumerEventMessage message = new ConsumerEventMessage() {
            Message = "Test"
        };
        
        // Causes an event to raise automatically when Consume is invoked
        _consumerHandlerMock
            .Setup(_ => _.Consume(It.IsAny<string>(), It.IsAny<CancellationToken>()))
            .Raises(_ => _.HandleConsumeMessageEvent += null, message);
    
        // Act
        await _fetchNotificationDataByApplicationIdConsumer.StartAsync(CancellationToken.None);
       
        // Assert....
    }