簡體   English   中英

用於驗證模擬方法是否調用的通用方法

[英]Generic method for verifying whether a mocked method called

我正在構建通用測試輔助方法來驗證是否在具有給定類型的模擬中調用了一個方法。 在我的示例中,我正在嘲笑IMediator庫中的IMediator 為了模擬,我使用的是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您會發現兩種方法:

  1. 接收IRequest<TResponse>

  2. 接收object

真正弄清楚要使用哪個覆蓋對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);
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM