TOC
Исходя из того что теперь вы знаете что такое авто-мок, хочу Вас обрадовать ещё одной штукой: AutoFixture - библиотекой разработанной Mark Seemann-ом которая предоставляет функционал автомока. О том как им воспользоваться и будет этот перевод статьи с блога автора.
Внутренняя архитектура AutoFixture предоставляет новые и интересные функции. Одна из них заключается в том, что появилась возможность легко расширять AutoFixture, таким образом делая полноценным DI-контейнером.
Лично я использую Moq, пакет AutoFixture уже включает новую сборку под названием AutoMoq, который содержит в себе расширение предоставляющее возможность использовать Moq при создании тестовых двойников.
Имейте в виду, что сборка AutoFixture сама по себе не зависит от Moq. Если вы не хотите использовать Moq, вы можете просто игнорировать сборку AutoFixture.AutoMoq.
В Auto-mock из AutoFixture не обязательно использовать Moq. Хотя он поставляется с поддержкой Moq, можно написать расширение для другой библиотеки динамических моков.
Чтобы использовать его, вы должны сначала добавить ссылку на AutoFixture.AutoMoq. Теперь вы можете создать свой экземпляр Fixture следующим образом:
var fixture = new Fixture()
.Customize(new AutoMoqCustomization());
Этот код добавляет новый функционал в Fixture. Если тип проваливается через обычный Fixture-движок без обработки, расширение auto-mock проверяет, нужны ли этому типу сущьности интерфейсов или абстрактных классов. Если это так, он будет делегировать этот запрос на запрос Mock-а того же типа.
Другая часть расширений обрабатывает запросы на Mock-и, что гарантирует, что Mock будет создан и возвращен.
Разделение работы автомока на делегирование и стратегию создания свойств Mock-а также означает, что мы можем напрямую запросить Mock, если мы хотим этого. Более того, мы можем использовать встроенную поддержку метода Freeze для замораживания Mock-а, а также автоматически замораживать и экземпляр автомока (потому что делегиорвание запросит Mock, который окажется замороженным).
Возвращаясь к первому примеру «замороженной» пиццы, мы можем теперь переписать его так:
[Fact]
public void AddWillPipeMapCorrectly()
{
// Fixture setup
var fixture = new Fixture()
.Customize(new AutoMoqCustomization());
var basket = fixture.Freeze<Basket>();
var mapMock = fixture.Freeze<Mock<IPizzaMap>>();
var pizza = fixture.CreateAnonymous<PizzaPresenter>();
var sut = fixture.CreateAnonymous<BasketPresenter>();
// Exercise system
sut.Add(pizza);
// Verify outcome
mapMock.Verify(m => m.Pipe(pizza, basket.Add));
// Teardown
...
}
Обратите внимание, что мы можем просто заморозить Mock, который также автоматически заморозит экземпляр IPizzaMap. Когда мы позже создаем SUT, запросив анонимный BasketPresenter, IPizzaMap уже “вморожен” в Fixture, поэтому правильный экземпляр будет внедрён в SUT.
comments powered by Disqus