我很难测试使用.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
调用可以正常工作。
答案 0 :(得分:2)
在这种情况下,创建返回更多模拟的模拟可能无济于事。您的课程取决于IServiceProvider
,因此您需要致电CreateScope()
。
模拟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);
对我来说,这比创建返回更多模拟的模拟更为简单和容易。