我正在构建通用的测试助手方法,以验证是否在给定类型的模拟中调用了某个方法。在我的示例中,我IMediator
从MediatR库中嘲笑。为了嘲笑我正在使用Moq库
让我们看一下代码。为了简单起见,我做了一个“虚拟”服务和相应的测试,仅关注此问题。我的生产代码:
public class Service
{
private readonly IMediator _mediator;
public Service(IMediator mediator)
{
_mediator = mediator;
}
public void SendQuery()
{
_mediator.Send(new GetAllProductsQuery());
}
}
并进行相应的测试:
[Fact]
public void WhenSendQueryCalled_ThenGetAllProductsQuerySend()
{
//Arrange
var mockedMediator = new Mock<IMediator>();
var service = new Service(mockedMediator.Object);
//Act
service.SendQuery();
//Assert
CheckThatRequestSentViaMediator<GetAllProductsQuery>(mockedMediator);
}
private void CheckThatRequestSentViaMediator<TRequest>(Mock<IMediator> mockedMediator) where TRequest : class
{
mockedMediator.Verify(mock => mock.Send(It.IsAny<TRequest>(), It.IsAny<CancellationToken>()), Times.Once);
}
我的assert方法确实由于以下原因意外失败:
Moq.MockException:
Expected invocation on the mock once, but was 0 times: mock => mock.Send(It.IsAny<GetAllProductsQuery>(), It.IsAny<CancellationToken>())
Performed invocations:
Mock<IMediator:1> (mock):
另一方面,如果我直接在验证方法中指定类型,则测试通过。传递的assert方法如下所示:
private void CheckGetAllProductsQuerySentViaMediator(Mock<IMediator> mockedMediator)
{
mockedMediator.Verify(mock => mock.Send(It.IsAny<GetAllProductsQuery>(), It.IsAny<CancellationToken>()), Times.Once);
}
对我来说,这很奇怪,因为第二个assert方法存在缺陷。但是,如果我使用通用类型参数并将其粘贴到verify方法上,它将失败。我究竟做错了什么?我是否不了解C#/。NET.Core的一些重要基础行为?谢谢您的帮助!
看来问题出在您的约束上where TRequest : class
。
如果您查看,IMediator
则会发现两种方法:
moq
真正弄清楚要使用哪个替代值是令人困惑的。尝试对类型进行明确说明,以真正指向正确的方法,例如:
private static void CheckThatRequestSentViaMediator<T>(Mock<IMediator> mediator)
where T : IRequest<T>
要么
private static void CheckThatRequestSentViaMediator<T>(Mock<IMediator> mediator) where T : class
{
mediator.Verify(mock => mock.Send(It.IsAny<IRequest<T>>(), It.IsAny<CancellationToken>()), Times.Once);
}
谢谢您的回答,不胜感激!您是否尝试过解决方案?对我来说,它仍然不起作用,不幸的是,它失败了...
但是给您答案,现在我知道出了什么问题,谢谢!
@ mirind4实际上我已经尝试过,如果它不起作用很奇怪...
我在IRequest <T>上使用了另一个抽象,这就是问题所在。