Исключение Moq: ожидаемый вызов на макет один раз, но был 0 раз ... -. Net Core 3.1 с xUnit - PullRequest
3 голосов
/ 09 января 2020

Я новичок в Moq и пытаюсь реализовать 2 теста, которые проверяют наличие HttpStatusCode.NotModified и HttpStatusCode.Ok. Тем не менее, последний проходит свой тест, но первый не проходит и возвращает исключение:

Moq.MockException: ожидаемый вызов на макет один раз, но был 0 раз: x => x.UpdateStateAsyn c (It.Is (y => y == RedisServiceModel))

Вот HttpStatusCode.Ok, который передает:

        [Fact]
        public void UpdateState_StateHasBeenUpdated_HttpOk()
        {
            //arrange
            var state = new RedisServiceModel();
            var redisServiceMock = new Mock<IRedisService>();
            redisServiceMock.Setup(x => x.UpdateStateAsync(It.Is<RedisServiceModel>(y => y == state))).ReturnsAsync(state);
            var testController = new TestController(redisServiceMock.Object);

            // act
            var statusResult = testController.UpdateStates(state);

            // assert
            redisServiceMock.Verify(x => x.UpdateStateAsync(It.Is<RedisServiceModel>(y => y == state)));
            Assert.True(statusResult.Result is HttpStatusCode.OK);
        }

Вот HttpStatusCode.NotModified который выдает исключение:

        [Fact]
        public void UpdateState_StateHasNotBeenModified_HttpNotModified()
        {
            //arrange
            var state = new RedisServiceModel();
            var redisServiceMock = new Mock<IRedisService>();
            redisServiceMock.Setup(x => x.UpdateStateAsync(It.Is<RedisServiceModel>(y => y == state))).ReturnsAsync(state);
            var testController = new TestController(redisServiceMock.Object);

            // act
            var statusResult = testController.UpdateStates(null);

            // assert
            redisServiceMock.Verify(x => x.UpdateStateAsync(It.Is<RedisServiceModel>(y => y == state)), Times.Once);
            Assert.True(statusResult.Result is HttpStatusCode.NotModified);
        }

Вот вызов API PUT:

        [HttpPut]
        [Route("updatestates")]
        public async Task<HttpStatusCode> UpdateStates(RedisServiceModel update)
        {
            RedisServiceModel updateState = await _redisService.UpdateStateAsync(update);

            if (updateState != null)
            {
                return HttpStatusCode.OK;
            }

            return HttpStatusCode.NotModified;
        }

Я предполагаю его, потому что я передаю null здесь testController.UpdateStates(null) , Я попытался обернуть все в методе UpdateStates api, чтобы null проверил аргумент update, но это все равно привело к тому же исключению. Если вам понадобится код, дайте мне знать, и я отредактирую этот пост.

Ответы [ 2 ]

2 голосов
/ 09 января 2020

Субъекта следует ожидать, в противном случае утверждение может быть сделано до того, как субъект завершил ожидаемое поведение.

. Кроме того, макет должен быть настроен на возврат переданного аргумента в mimi c ожидаемое поведение объекта. фактическая реализация

[Fact]
public async Task UpdateState_StateHasNotBeenModified_HttpNotModified() {
    //arrange
    var state = new RedisServiceModel();
    var redisServiceMock = new Mock<IRedisService>();
    redisServiceMock
        .Setup(x => x.UpdateStateAsync(It.IsAny<RedisServiceModel>()))
        .ReturnsAsync(x => x);
    var testController = new TestController(redisServiceMock.Object);

    // act
    var statusResult = await testController.UpdateStates(null);

    // assert
    redisServiceMock.Verify(x => x.UpdateStateAsync(It.Is<RedisServiceModel>(y => y == null)), Times.Once);
    Assert.True(statusResult is HttpStatusCode.NotModified);
}

То же самое должно было быть сделано для другого теста

[Fact]
public async Task UpdateState_StateHasBeenUpdated_HttpOk()
{
    //arrange
    var state = new RedisServiceModel();
    var redisServiceMock = new Mock<IRedisService>();
    redisServiceMock
        .Setup(x => x.UpdateStateAsync(It.Is<RedisServiceModel>()))
        .ReturnsAsync(x => x);
    var testController = new TestController(redisServiceMock.Object);

    // act
    var statusResult = await testController.UpdateStates(state);

    // assert
    redisServiceMock.Verify(x => x.UpdateStateAsync(It.Is<RedisServiceModel>(y => y == state)));
    Assert.True(statusResult is HttpStatusCode.OK);
}

Тем не менее, действие субъекта должно быть рефакторировано, чтобы следовать правильному синтаксису для контроллеров.

Предполагая, что контроллер получен из ControllerBase, он будет иметь доступ к вспомогательным методам для результатов действий.

[HttpPut]
[Route("updatestates")]
public async Task<IActionResult> UpdateStates(RedisServiceModel update) {
    RedisServiceModel updateState = await _redisService.UpdateStateAsync(update);

    if (updateState != null) {
        return Ok();
    }

    return StausCode((int)HttpStatusCode.NotModified);
}
1 голос
/ 09 января 2020

Проблема в том, что вы проверяете между null и state, которые не равны. Функция была вызвана, но с нулем, вместо состояния (равенство на ссылке).

Попробуйте с этим:

        [Fact]
        public void UpdateState_StateHasNotBeenModified_HttpNotModified()
        {
            //arrange
            var state = new RedisServiceModel();
            var redisServiceMock = new Mock<IRedisService>();
            redisServiceMock.Setup(x => x.UpdateStateAsync(It.Is<RedisServiceModel>(y => y == state))).ReturnsAsync(state);
            var testController = new TestController(redisServiceMock.Object);

            // act
            var statusResult = testController.UpdateStates(null);

            // assert
            redisServiceMock.Verify(x => x.UpdateStateAsync(It.Is<RedisServiceModel>(y => y == null)), Times.Once);
            Assert.True(statusResult.Result is HttpStatusCode.NotModified);
        }
...