Модульный тест с использованием AutoFixture, чтобы гарантировать запись в возвращенном списке объектов - PullRequest
0 голосов
/ 21 мая 2018

Я пишу модульный тест, который проверяет, что метод контроллера возвращает список объектов.Мой модульный тест написан с использованием xUnit и AutoFixture, а код выглядит следующим образом:

// Arrange
var mockEmployeeRepo = new Mock<IEmployeeRepository>();
var employeeAccountsReturn = new Fixture().Create<List<Contracts.EmployeeAccount>>();
mockEmployeeRepo.Setup(employeeRepo => employeeRepo.GetEmployeeAccountsByEmployeeAccountId(It.IsAny<int>()))
    .Returns(employeeAccountsReturn);
var employeeAccountController = new EmployeeAccountController(mockEmployeeRepo.Object);

// Act
var result = employeeAccountController.GetEmployeeAccounts(1);

// Assert
Assert.Equal(employeeAccountsReturn, result);

Я получил отзыв об этом коде, спрашивающий, является ли этот модульный тест детерминированным, гарантирует ли создание через Fixture запись всписок.Относится ли вышеуказанное к моему коду модульного теста?Как я могу использовать Fixture, чтобы гарантировать запись в списке?

Спасибо!

Ответы [ 2 ]

0 голосов
/ 21 мая 2018

Является ли тест детерминированным, как написано?Это зависит от того, как вы интерпретируете «детерминистический».Обычно, когда вы запускаете набор модульных тестов, тестовый прогон выдает различную статистику о тестовом прогоне, например, когда он был выполнен, сколько времени он занял и так далее.При рассмотрении на этом уровне никакие тестовые наборы никогда не будут детерминированными.

Если, с другой стороны, вы ссылаетесь на детерминизм, связанный с тестами , поскольку Мартин Фаулер обсуждает его , вышеуказанный тест может быть «достаточно детерминированным».Это, в конечном счете, зависит от предполагаемой реализации SUT.

Автофиксирование при создании случайных значений разработано с намерением, чтобы оно создавало контрольные примеры, которые все попадают в один и тот же Класс эквивалентности .В этом конкретном случае он никогда не создает пустые списки, но если вы хотите сделать это явным в своем тесте, вы всегда можете добавить Guard Assertion :

var employeeAccountsReturn = new Fixture().CreateMany<Contracts.EmployeeAccount>();
// Guard Assertion:
Assert.NotEmpty(employeeAccountsReturn);
mockEmployeeRepo
    .Setup(employeeRepo => employeeRepo.GetEmployeeAccountsByEmployeeAccountId(It.IsAny<int>()))
    .Returns(employeeAccountsReturn);

Вы также можете сделатьболее очевидно, что вы создаете коллекцию с использованием метода CreateMany:

var employeeAccountsReturn = new Fixture().CreateMany<Contracts.EmployeeAccount>();

В этом конкретном случае, будет ли иметь значение, если коллекция будет пустой?Разве тест не пройдет?Не так ли?

0 голосов
/ 21 мая 2018

Я бы сказал, что этот тест не будет детерминированным, если вы используете AutoFixture для генерации случайного списка объектов EmployeeAccount.Вы будете полагаться на AutoFixture для создания одного и того же списка при каждом запуске, что, я уверен, не так.

Если вы действительно пишете здесь модульный тест, я бы спросил вас, что это делаетметод контроллера делать?Сколько бизнес-логики содержится в самом контроллере?Если GetEmployeeAccounts просто вызывает хранилище и возвращает этот результат, то я думаю, что вы на правильном пути.Вы также можете проверить, что ошибки обрабатываются правильно, и контроллер возвращает значимый статус ошибки.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...