Имитация нескольких экземпляров интерфейса: настройка последнего макета влияет на другие

После моего вопроса о условно-зависимом разрешении во время выполнения

Я создал BooService с внедренным массивом IFooService[] и методом FooFactory, который возвращает одну из служб foo на основе заданного ключа во время выполнения.

class BooService
{
    readonly IFooService[] _fooServices;

    BooService(IFooService[] services)
    {
        this._fooServices = services;
    }
    IFooService FooFactory(Guid id)
    {
        IFooService fooService = Array.Find(this._fooServices, 
                                     service => service.Id == id);
        return fooService;
    }
}

public class FooService1 : IFooService
{
    public int Id { get { return 1; }  
}
public class FooService2 : IFooService
{
    public int Id { get { return 2; }  
}

Все работает нормально во время выполнения, но мои UnitTests терпят неудачу:

AutoMock _mock = Autofac.Extras.Moq.AutoMock.GetLoose();
Mock<IFooService> fooService1 = _mock.Mock<IFooService>();
fooService1
    .Setup(x => x.Id)
    .Returns(1);

Mock<IFooService> fooService2 = _mock.Mock<IFooService>();
fooService2
    .Setup(x => x.Id)
    .Returns(2);

IFooService[] fooServices = new IFooService[] { fooService1.Object, fooService2.Object };

BooService booService = new BooService(fooServices);
booService.FooFactory(1); //Result in null
booService.FooFactory(2); //Result in "fooService2"

Для идентификатора 1 код строки Array.Find(this._fooServices, ...); приводит к null!

Когда я комментирую создание второго экземпляра фиктивного интерфейса, код booService.FooFactory(1); приводит к fooService1. Итак, я предполагаю, что второй Setup как-то влияет на первый экземпляр.

Любое предложение, почему при создании двух фиктивных экземпляров интерфейса Array.Find(...) находит только последний созданный фиктивный экземпляр?

Если это ошибка в Moq: какой-либо чистый обходной путь для модульного тестирования процесса поиска?


person Shahar Shokrani    schedule 04.09.2019    source источник


Ответы (1)


_mock.Mock<IFooService>()

Будет возвращать один и тот же имитированный экземпляр для каждого вызова, поэтому настройка фактически выполняется на одном экземпляре. Последняя установка выигрывает каждый раз.

Вот ручной подход

IFooService fooService1 = Mock.Of<IFooService>(_ => _.Id == 1);
IFooService fooService2 = Mock.Of<IFooService>(_ => _.Id == 2);

IFooService[] fooServices = new IFooService[] { fooService1.Object, fooService2.Object };
person Nkosi    schedule 04.09.2019