Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Async event mocking hides exception #1352

Closed
ms-lemos opened this issue Jul 18, 2023 · 3 comments
Closed

Async event mocking hides exception #1352

ms-lemos opened this issue Jul 18, 2023 · 3 comments

Comments

@ms-lemos
Copy link

Hello there!

It seems that when an exception is raised inside an event raise, it gets caught by Moq and it goes undetected. Might have to do with it being async?

Example:

internal class Program
{
   static async Task Main(string[] args)
   {
       var eventManager = new EventManager();
       var eventConsumer = new EventConsumer(eventManager);

       await eventManager.OnEventHappened(1000);

       Console.WriteLine("Unreacheble, exception thrown");
   }
}

public delegate Task CustomEvent(int number);

public interface IEventManager
{
   event CustomEvent CustomEvent;
}

public class EventConsumer
{
   private readonly IEventManager _eventManager;

   public EventConsumer(IEventManager eventManager)
   {
       _eventManager = eventManager;

       _eventManager.CustomEvent += _eventManager_CustomEvent;
   }

   private async Task _eventManager_CustomEvent(int number)
   {
       await Task.Delay(number);
       throw new NotImplementedException();
   }
}

public class EventManager : IEventManager
{
   public event CustomEvent CustomEvent;

   public async Task OnEventHappened(int number)
   {
       await CustomEvent.Invoke(number);
   }
}

Failing tests:

[Test]
public void ShouldThrowException()
{
    var eventManagerMock = new Mock<IEventManager>(MockBehavior.Strict);
    var consumer = new EventConsumer(eventManagerMock.Object);

    Assert.Throws<NotImplementedException>(() => eventManagerMock.Raise(x => x.CustomEvent += null, 1000));
}

[Test]
public void ShouldThrowException2()
{
    var eventManagerMock = new Mock<IEventManager>(MockBehavior.Strict);
    var consumer = new EventConsumer(eventManagerMock.Object);

    eventManagerMock.Setup(x => x.OnEventHappened(1000)).Returns(Task.CompletedTask).Raises(x => x.CustomEvent += null, 1000);

    Assert.Throws<NotImplementedException>(() => eventManagerMock.Object.OnEventHappened(1000));
}

Am I doing something wrong or is it a bug indeed?

Thanks!

@ms-lemos
Copy link
Author

Now I see https://github.com/moq/moq/pull/1313 and https://github.com/moq/moq/issues/977, sorry about the duplicate.

@ms-lemos
Copy link
Author

So that leaves another question, any updates on 4.19? I see the milestone is closed.

@ms-lemos
Copy link
Author

ms-lemos commented Aug 3, 2023

Tested with 4.20-beta, RaiseAsync and ThrowsAsync working together like a charm.

@ms-lemos ms-lemos closed this as completed Aug 3, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant