Пишем Тесты с Autofixture
AutoFixture - мощный инструмент для юнит-тестирования повседневных задач. Он помогает писать меньше кода в блоке Arrange. Рассмотрим его использование на примере совместно с библиотекой xUnit.
Сначала надо создать AutoFixture в тестовом классе:
private readonly IFixture _fixture;
public SampleTests()
{
_fixture = new Fixture();
}
AutoFixture использует обобщённый метод Create, генерирующий случайные данные для заданного типа, например:
var name = _fixture.Create<string>();
var age = _fixture.Create<int>();
Однако, с помощью дополнительного пакета AutoFixture.Xunit2, вы можете автоматически создавать целые классы, вообще без блока Arrange с помощью атрибута AutoData:
[Theory, AutoData]
public void TestEmployee(
string name, int age,
string pos, decimal rate)
{
// Act
var emp = new Employee(name, age, pos, rate);
// Assert
emp.Name.Should().Be(name);
emp.Age.Should().Be(age);
emp.Position.Should().Be(pos);
emp.Rate.Should().Be(rate);
}
Либо можно использовать метод Create:
[Fact]
public void TestEmployee()
{
// Arrange
var emp = _fixture.Create<Employee>();
var comp = _fixture.Create<Company>();
…
}
Здесь все свойства классов будут заданы случайными значениями.
Вы можете управлять созданием, задавая данные для определённых свойств. Также можно создавать коллекции элементов:
var emps = _fixture
.CreateMany<Employee>(5).ToList();
var comp = _fixture.Build<Company>()
.OmitAutoProperties()
.With(x => x.Employees, emps)
.Without(x => x.City)
.Create();
Здесь вызов OmitAutoProperties не будет задавать случайные значения свойствам, у которых есть значения по умолчанию. А Without не будет задавать значение выбранного свойства (в примере выше City останется null).
Вы можете создавать реализации интерфейсов с помощью метода Register:
_fixture.Register<IMyInterface>(() =>
new FakeMyInterface());
Здесь каждый раз, когда Autofixture нужно будет создать класс, зависящий от IMyInterface, будет создаваться экземпляр FakeMyInterface.
AutoFixture также можно использовать с пакетами для создания моков, вроде Moq или NSubstitute. Для этого надо настроить создание Autofixture (пример для Moq):
var _fixture = new Fixture()
.Customize(new AutoMoqCustomization
{ ConfigureMembers = true });
Тогда Autofixture можно будет использовать для создания реализаций интерфейсов:
var result = _fixture.Create<IMyInterface>();
При этом установка ConfigureMembers в true приводит к тому, что для классов-реализаций интерфейсов Autofixture сгенерирует случайные значения для свойств.
Здесь можно посмотреть множество других примеров использования AutoFixture.
Источник: https://dev.to/serhii_korol_ab7776c50dba/you-write-unit-tests-wrong-5d9f