Mock ServiceProvider GetServices - PullRequest
       14

Mock ServiceProvider GetServices

0 голосов
/ 22 февраля 2019

У меня трудные времена для тестирования Фабрики, которая использует ядро ​​.net ServiceProvider, чтобы вернуть конкретную реализацию с учетом некоторой логики.

using (var scope = _serviceProvider.CreateScope())
{
    var services = scope.ServiceProvider.GetServices<IUrlProcessor>();
}

У меня частично это есть с

var serviceProvider = new Mock<IServiceProvider>();
serviceProvider.Setup(m => m.GetService(typeof(IEnumerable<IUrlProcessor>)))
    .Returns(new List<IUrlProcessor>() {
        new PassthruProcessor()
    });

Кажется, GetServices работает, но вызов CreateScope только через исключение.Это метод расширения, я не знаю, какой именно класс я должен смоделировать, чтобы сработал вызов CreateScope.

1 Ответ

0 голосов
/ 22 февраля 2019

В этом сценарии это, вероятно, не помогает создавать макеты, которые возвращают больше макетов.Ваш класс зависит от IServiceProvider, и вам нужно позвонить CreateScope().

Mocking IServiceProvider для возврата другого макета функционально аналогичен использованию real ServiceProvider и настройке его для возврата макета.Разница в том, что если вы используете реальный ServiceProvider, вам также не придется издеваться над CreateScope.

(я полностью обхожу вопросы о том, где и когда зависеть от IServiceProvider.)

Вот резко упрощенный пример:

Класс, который зависит от IServiceProvider:

public class ScopedFooFactory : IFooFactory
{
    private readonly IServiceProvider _serviceProvider;

    public ScopedFooFactory(IServiceProvider serviceProvider)
    {
        _serviceProvider = serviceProvider;
    }

    public IFoo CreateFoo()
    {
        using (var scope = _serviceProvider.CreateScope())
        {
            return scope.ServiceProvider.GetService<IFoo>();
        }
    }
}

... и некоторый код модульного теста:

var serviceCollection = new ServiceCollection();
var fooMock = new Mock<IFoo>();
serviceCollection.AddScoped<IFoo>(provider => fooMock.Object);
var serviceProvider = serviceCollection.BuildServiceProvider();
var subject = new ScopedFooFactory(serviceProvider);
var foo = subject.CreateFoo();
Assert.AreSame(fooMock.Object, foo);

Для меня это проще и проще, чем создавать макет, который возвращает больше насмешек.

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