moq для медиатора, использующего дженерики в модульном тестировании - PullRequest
0 голосов
/ 10 апреля 2020

Я использую cqrs и mediatr в. net core 3 webapi project. Я хочу провести модульное тестирование поведения методов контроллера, поэтому, когда метод вызывается, медиатор работает должным образом. Я написал тестовый код для одного метода, и он отлично работает. Многие коды опущены для краткости, я использовал только тот код, который вызывает ошибку. Итак, рабочий тест:

        var mockScrapedAd = ScrapedAd.CreateMockAd(DateTime.Now); //result of controller method

         mediatrMock.Setup(m =>
             m.Send(It.IsAny<QueryDetails>(),
                 It.IsAny<CancellationToken>())).
             ReturnsAsync(() => mockScrapedAd); //mock for mediator,
         // so when something with QueryDetails type is called, it should return result from above

        var ret = await controller.Details(0); //should send QueryDetails via Mediatr

        Assert.Equal(mockScrapedAd, ret.Value); //all good?

       mediatrMock.Verify(x => x.Send(It.IsAny<QueryDetails>(), //was it called at all?
           It.IsAny<CancellationToken>()));

Этот тест работает, но мне придется дублировать код для каждого метода контроллера. Единственное, что здесь меняется, это тип запроса медиатора (здесь QueryDetails) и макет для возврата. Поэтому я попытался использовать метод generi c, как здесь:

    async Task TestBase<TK,K>(TK expectedResult,Func<Task<ActionResult<TK>>> callControllerMethod)
    {

        mediatrMock.Setup(m =>
            m.Send(It.IsAny<K>(),
                It.IsAny<CancellationToken>())).ReturnsAsync(() => expectedResult);

        var ret = await callControllerMethod();

        Assert.Equal(expectedResult, ret.Value);

       mediatrMock.Verify(x => x.Send(It.IsAny<K>(),
           It.IsAny<CancellationToken>()));

    }

И набор тестов будет проще:

     var mockScrapedAd = ScrapedAd.CreateMockAd(DateTime.Now);            

        await TestBase<ScrapedAd,QueryDetails>(mockScrapedAd, async () => await controller.Details(0));

В основном все, что я изменил, перемещено QueryDetails внутри generi c метод. Посредник не может распознать его, и ответ не называется. Что здесь не так?

...