Moq и настройка нескольких методов - PullRequest
1 голос
/ 23 февраля 2020

Я пытаюсь изучать как MOQ, так и модульное тестирование с xUnit одновременно.

У меня есть класс аутентификации logi c с несколькими методами. Все они используют AuthenticationDataAccessor. Я пытаюсь смоделировать этот метод доступа, чтобы сохранить изоляцию модульного теста только для logi c.

Я пытаюсь выполнить модульное тестирование logi c двух методов в моем классе logi c.

RegisterAsyn c и AuthenticateAsyn c

private void SetupMocks()
        {
            // Mock the data accessor.
            var _mockedDataAccessor = new Mock<IAuthenticationData>();

            // Moke the call that will go to the mocked data accessor.
            var _mockedAuthenticationRequest = new AuthenticationRequest { Username = It.IsAny<string>(), Password = It.IsAny<string>() };
            var _mockedRegistrationRequest = new RegistrationRequest { Email = It.IsAny<string>(), Password = It.IsAny<string>(), Firstname = It.IsAny<string>(), Surname = It.IsAny<string>()  };

            // Setup the accessor.
            _mockedDataAccessor
                .Setup(x => x
                .AuthenticateAsync(_mockedAuthenticationRequest))
                .ReturnsAsync(
                    new SharedLib.Responses.UserResponse
                    {
                        ResponseState = new SharedLib.Responses.ResponseState
                        {
                            Description = "Moq description",
                            IsSuccess = true,
                            ResponseCode = ResponseCode.OK,
                            SystemError = false
                        }
                    });


            _mockedDataAccessor
                .Setup(x => x
                .RegisterAsync(_mockedRegistrationRequest))
                .ReturnsAsync(
                    new SharedLib.Responses.RegistrationResponse
                    {
                        ResponseState = new SharedLib.Responses.ResponseState
                        {
                            Description = "Moq description",
                            IsSuccess = true,
                            ResponseCode = ResponseCode.OK,
                            SystemError = false
                        }
                    });


            // Create the logic reference based on the mocked data accessor
            _logic = new AuthenticationLogic(_mockedDataAccessor.Object);

        }

Итак, у меня два вызова настройки. Один из них для метода доступа к данным. Я ожидал бы, что это будет то, что я установил в своей настройке выше.

Обратите внимание, что тест, использующий мою проверку подлинности Authenticate, работает. Кажется, 2-й макет не удается.

[Fact]
        public async void BlankUsernameReturnsError()
        {
            SetupMocks();

            var result = await _logic.AuthenticateAsync(new AuthenticationRequest
            {
                Password = "AFantastic123Password@",
                Username = "",
            });

            Assert.Equal(ResponseCode.LoginInvalidCredentials, result.ResponseState.ResponseCode);
        }

Это работает. Может быть, у вас не может быть двух «установок» в одном и том же классе? И мне нужно иметь конкретную настройку c на тест? Может быть, private void Setup() это проблема / плохая идея?

1 Ответ

2 голосов
/ 23 февраля 2020

Основная проблема c, с которой вы столкнулись, заключается в следующем:

_mockedDataAccessor
    .Setup(x => x.AuthenticateAsync(_mockedAuthenticationRequest))
    .ReturnsAsync(...));

... говорит Moq вести себя определенным образом, когда AuthenticateAsync() передается именно этому параметру . Поскольку это не то, что проходят ваши тесты, вместо этого начните со сценария «поймать все»:

_mockedDataAccessor
    .Setup(x => x.AuthenticateAsync(It.IsAny<AuthenticationRequest>()))
    .ReturnsAsync(...));

Затем вы можете сузить требование, если это необходимо, в зависимости от того, чего пытается достичь ваш тест; Например, вы можете вернуть одно значение, когда Имя пользователя «Алиса», и другое, если это «Боб»:

_mockedDataAccessor
    .Setup(x => x.AuthenticateAsync(It.Is<AuthenticationRequest>(a => a.Username == "Alice")))
    .ReturnsAsync(...one value...));
_mockedDataAccessor
    .Setup(x => x.AuthenticateAsync(It.Is<AuthenticationRequest>(a => a.Username == "Bob")))
    .ReturnsAsync(...something else...));
...