Поскольку AutoFixture может создавать анонимные делегаты , при запросе на создание анонимного экземпляра SystemUnderTest
он также автоматически предоставляет анонимный делегат Func<IMyClass>
, который, в свою очередь, возвращает анонимный экземплярIMyClass
при вызове.
Это означает, что для данного сценария:
public class SystemUnderTest
{
public SystemUnderTest(Func<IMyClass> c)
{
try
{
var c1 = c();
// ...
}
catch (Exception)
{
var c2 = c();
// ...
}
}
}
следующий код:
var fixture = new Fixture();
var sut = fixture.CreateAnonymous<SystemUnderTest>();
назначит c1
и c2
переменных с анонимными экземплярами IMyClass
.Кроме того, если вы сконфигурируете AutoFixture так, чтобы работал как контейнер для автоматической имитации , например, с использованием AutoMoqCustomization
, эти анонимные экземпляры IMyClass
также будут являться прокси Moq:
var fixture = new Fixture();
fixture.Customize(new AutoMoqCustomization());
var sut = fixture.CreateAnonymous<SystemUnderTest>();
Однако эта информация, хотя и полезная, на самом деле не помогает вам в вашем конкретном случае, так как вам нужно овладеть ложными объектами , возвращаемыми фабрикой Func<IMyClass>
метод в вашем тесте, чтобы настроить их поведение и сделать некоторые утверждения о том, как с ними взаимодействовали.
На мой взгляд, лучшее решение - изменить реализацию фабричного метода от Func<IMyClass>
до интерфейс .Таким образом, вы можете создать фальшивую фабрику, которая возвращает различные макеты интерфейса IMyClass
, когда метод Create
вызывается несколько раз в последовательности :
Итак, учитывая этот пример:
public interface IFactory<T>
{
T Create();
}
public class SystemUnderTest
{
public SystemUnderTest(IFactory<IMyClass> factory)
{
try
{
var c1 = factory.Create();
// ...
}
catch (Exception)
{
var c2 = factory.Create();
// ...
}
}
}
Вы можете настроить свой тестовый сценарий следующим образом:
// Given
var c1 = new Mock<IMyClass>();
var c2 = new Mock<IMyClass>();
// TODO: setup the behavior of the mock objects
var factory = new Mock<IFactory<IMyClass>>();
factory.Setup(s => s.Create()).ReturnsInOrder(c1.Object, c2.Object);
// When
var fixture = new Fixture();
fixture.Inject(() => factory.Object)
var sut = fixture.CreateAnonymous<SystemUnderTest>();
// Then
// TODO: verify the expectations on the mock objects
Обратите внимание, что ReturnsInOrder
- это пользовательский метод расширения который использует метод Callback
в Moq для возврата различных значений из метода-заглушки, когда он вызывается несколько раз подряд.