![](/img/trans.png)
[英]How do I inject an instance of an objct into the “create” function of .NET Core DI Container
[英]How do I inject fake into DI container?
我正在尝试将伪造品注入DI容器中,并且我希望使用伪造品来代替Startup中指定的伪造品。 我试过了
var topicWriterFake = A.Fake<IServiceBusTopicWriter>();
A.CallTo(() => topicWriterFake.Write(A<string>.Ignored, A<string>.Ignored))
.Returns(Task.CompletedTask);
var webHostBuilder = WebHost.CreateDefaultBuilder().UseStartup<Startup>();
webHostBuilder.ConfigureServices(sc => sc.AddScoped(p => topicWriterFake));
var serviceProvider = new DependencyResolver(_webHostBuilder.Build());
var sut = serviceProvider.GetService<IStripeService>();
IStripeService依赖于IServiceBusTopicWriter。 上面的代码解析IStripeService时,它仍使用在Startup中连接的实例,而不是通过测试中的ConfigureServices方法提供的实例。 有什么想法可行吗?
当将Web Host Builder与WebHostBuilder.ConfigureServices
一起使用时,在构建Web Host的特定时间将注册在Builder上配置的服务。 但是, Startup
类中的ConfigureServices
在那之后被调用。
因此,尽管可以在构建器上使用ConfigureServices
将服务添加到Web主机,但是Startup
仍然允许您覆盖所有内容。 这通常是一件好事,但是当您想对应用程序进行集成测试时,当然不会帮到您。
我建议您使用新的WebApplicationFactory
编写集成测试。 它已经带有许多实用程序,可以帮助您进行集成测试 。
工厂允许您做的一件事就是注入模拟服务进行测试 。 您可以在Web主机构建器上使用ConfigureTestServices
扩展方法 。
在IStartupConfigureServicesFilter
,Web应用程序工厂使用IStartupConfigureServicesFilter
来完成这项工作。 您可以在应用程序中注册其实现,它们的ConfigureServices
方法将运行以为Startup
类型设置服务配置管道。 因此,您可以注册多个配置操作,并在最后显式运行它们。
因此,如果由于某种原因您不能或不想使用Web应用程序工厂(尽管这使集成测试容易得多),您仍然可以像下面这样明确地使这项工作:
var webHostBuilder = WebHost.CreateDefaultBuilder()
.UseStartup<Startup>()
.ConfigureServices(services =>
{
services.AddSingleton<IStartupConfigureServicesFilter>(new MockInjectorFilter(s =>
{
s.AddScoped(p => topicWriterFake);
});
});
public class MockInjectorFilter : IStartupConfigureServicesFilter
{
private readonly Action<IServiceCollection> _configureServices;
public ConfigureTestServicesStartupConfigureServicesFilter(Action<IServiceCollection> configureServices)
=> _configureServices = configureServices ?? throw new ArgumentNullException(nameof(configureServices));
public Action<IServiceCollection> ConfigureServices(Action<IServiceCollection> next)
=> serviceCollection =>
{
next(serviceCollection);
_configureServices(serviceCollection);
};
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.