似乎当在事件引发内引发异常时,它会被 Moq 捕获并且未被检测到。可能与异步有关? (陷入 Task.Exception 内部)。
示例:
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);
}
}
例如,这些测试失败(预期异常但为空)。
[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.ThrowsAsync<NotImplementedException>(() => eventManagerMock.Object.OnEventHappened(1000));
}
我做错了什么还是确实是一个错误?
我已经在moq's repro上提出了一个问题,但到目前为止还没有得到回复。
谢谢!
这似乎确实是一个可以通过 RaiseAsync 方法解决的问题,但在撰写本文时,它尚未发布。
一旦发布并确认解决问题,我将更新此答案。
https://github.com/moq/moq/blob/main/CHANGELOG.md
编辑:它似乎确实解决了问题,但由于赞助商链接的争议,我最终迁移到 NSubstitute,所以我无法确认它是否确实解决了问题。如果有人测试并可以确认,请发表评论,我会接受答案。