模拟服务提供者 GetServices
Mock ServiceProvider GetServices
我很难测试使用 .net 核心的工厂 ServiceProvider
到 return 给定一些逻辑的特定实现。
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
调用只是通过异常。这是一种扩展方法,我不知道确切的 class 是什么,我应该模拟以便 CreateScope
调用有效。
在这种情况下,创建 return 更多模拟可能无济于事。你的 class 依赖于一个 IServiceProvider
,你需要调用 CreateScope()
。
模拟 IServiceProvider
到 return 另一个模拟在功能上与使用 真实 ServiceProvider
并将其配置为 return 一个嘲讽。不同之处在于,如果你使用真实的 ServiceProvider
,你就不必模拟 CreateScope
。
(我完全回避了有关何时何地依赖 IServiceProvider.
的问题)
这是一个大大简化的例子:
依赖于IServiceProvider
的class:
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);
对我来说,这比创建一个 return 更多模拟的模拟更简单、更容易。
我很难测试使用 .net 核心的工厂 ServiceProvider
到 return 给定一些逻辑的特定实现。
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
调用只是通过异常。这是一种扩展方法,我不知道确切的 class 是什么,我应该模拟以便 CreateScope
调用有效。
在这种情况下,创建 return 更多模拟可能无济于事。你的 class 依赖于一个 IServiceProvider
,你需要调用 CreateScope()
。
模拟 IServiceProvider
到 return 另一个模拟在功能上与使用 真实 ServiceProvider
并将其配置为 return 一个嘲讽。不同之处在于,如果你使用真实的 ServiceProvider
,你就不必模拟 CreateScope
。
(我完全回避了有关何时何地依赖 IServiceProvider.
的问题)
这是一个大大简化的例子:
依赖于IServiceProvider
的class:
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);
对我来说,这比创建一个 return 更多模拟的模拟更简单、更容易。