C# 如何使用WebApplicationFactory在TestServer中切换服务?
我正在使用自定义WebApplication factoryC# 如何使用WebApplicationFactory在TestServer中切换服务?,c#,asp.net-core,xunit,C#,Asp.net Core,Xunit,我正在使用自定义WebApplication factory 公共类CustomWebApplicationFactory:WebApplicationFactory,其中TStartup:class{ 受保护的覆盖无效配置WebHost(IWebHostBuilder){ builder.ConfigureServices(服务=>{ //创建一个新的服务提供商。 var serviceProvider=newservicecolection() .AddEntityFrameworkInMe
公共类CustomWebApplicationFactory:WebApplicationFactory,其中TStartup:class{
受保护的覆盖无效配置WebHost(IWebHostBuilder){
builder.ConfigureServices(服务=>{
//创建一个新的服务提供商。
var serviceProvider=newservicecolection()
.AddEntityFrameworkInMemoryDatabase()
.BuildServiceProvider();
services.AddDbContext(选项=>{
选项。使用MemoryDatabase(“GrabGoDb”);
选项。使用InternalServiceProvider(serviceProvider);
});
services.AddSingleton();
services.AddScoped();//您可以根据环境进行操作。这只是为您指明正确方向的代码
public IHostingEnvironment HostingEnvironment { get; }
public void ConfigureServices(IServiceCollection services)
{
if (HostingEnvironment.IsDevelopment())
{
services.AddTransient<ITestService, TestService>();
}
else
{
services.AddTransient<IRealService, RealService>();
}
// other services
}
public IHostingEnvironment HostingEnvironment{get;}
public void配置服务(IServiceCollection服务)
{
if(HostingEnvironment.IsDevelopment())
{
services.AddTransient();
}
其他的
{
services.AddTransient();
}
//其他服务
}
我希望这能有所帮助。我刚刚花了几个小时尝试做类似的事情(覆盖集成测试中的服务)。结果是ConfigureServices
在SUT(测试对象)之前运行服务配置。ConfigureTestServices
,但是,它在之后运行,并且是您将使用模拟覆盖的地方
文件对此一点也不清楚,尽管我在事后发现:
您应该能够在ConfigureWebHost中执行此操作,如下所示:
public class CustomWebApplicationFactory : WebApplicationFactory<Startup>
{
protected override void ConfigureWebHost(IWebHostBuilder builder)
{
builder.ConfigureServices(services =>
{
// Remove application IEmailProvider service
var emailProviderDescriptor = services.SingleOrDefault(d => d.ServiceType == typeof(IEmailProvider));
if (emailProviderDescriptor != null)
{
services.Remove(emailProviderDescriptor);
}
// Add new test service(s)
services.AddScoped<IEmailProvider, TestEmailProvider>();
services.AddSingleton<TestEmailServer>(); // May need to remove using the descriptor similar to IEmailProvider
// Remove the app's GrabGoContext registration, add in memory one then seed data.
var dbDescriptor = services.SingleOrDefault(d => d.ServiceType == typeof(DbContextOptions<GrabGoContext>));
if (dbDescriptor != null)
{
services.Remove(dbDescriptor);
}
services.AddDbContext<GrabGoContext>(options =>
{
options.UseInMemoryDatabase("InMemoryDbForTesting");
});
var serviceProvider = services.BuildServiceProvider();
using var scope = serviceProvider.CreateScope();
var scopedServices = scope.ServiceProvider;
var grabGoContext = scopedServices.GetRequiredService<GrabGoContext>();
// Seed your db here & save..
grabGoContext.SaveChanges();
});
base.ConfigureWebHost(builder);
}
}
公共类CustomWebApplicationFactory:WebApplicationFactory
{
受保护的覆盖无效配置WebHost(IWebHostBuilder)
{
builder.ConfigureServices(服务=>
{
//删除应用程序IEmailProvider服务
var emailProviderDescriptor=services.SingleOrDefault(d=>d.ServiceType==typeof(IEmailProvider));
if(emailProviderDescriptor!=null)
{
删除(emailProviderDescriptor);
}
//添加新的测试服务
services.addScope();
services.AddSingleton();//可能需要使用类似于IEmailProvider的描述符删除
//删除应用程序的GrabGoContext注册,在内存中添加一个,然后添加种子数据。
var dbDescriptor=services.SingleOrDefault(d=>d.ServiceType==typeof(DbContextOptions));
if(dbDescriptor!=null)
{
删除(dbDescriptor);
}
services.AddDbContext(选项=>
{
选项。使用MemoryDatabase(“InMemoryDBforesting”);
});
var serviceProvider=services.BuildServiceProvider();
使用var scope=serviceProvider.CreateScope();
var scopedServices=scope.ServiceProvider;
var grabGoContext=scopedServices.GetRequiredService();
//在此处设置数据库种子并保存。。
grabGoContext.SaveChanges();
});
base.ConfigureWebHost(构建器);
}
}
您可能想让自己变得更容易,只需实现工厂,如上面所述,而不是保持它的通用性
它还没有被编译,但是语法应该不会太离谱。
希望这能有所帮助。我不这么认为,但我不想把真实代码和测试代码混为一谈。那么你想实现什么呢?我想更改默认应用程序行为(可能会覆盖它)使其适用于集成测试。但我的应用程序代码库中不应该有任何与测试相关的内容。哦……这看起来是一个解决方案,有点。谢谢,但我正在寻找更平滑的东西。如果我找不到,我可能会用你的想法:)
public class CustomWebApplicationFactory : WebApplicationFactory<Startup>
{
protected override void ConfigureWebHost(IWebHostBuilder builder)
{
builder.ConfigureServices(services =>
{
// Remove application IEmailProvider service
var emailProviderDescriptor = services.SingleOrDefault(d => d.ServiceType == typeof(IEmailProvider));
if (emailProviderDescriptor != null)
{
services.Remove(emailProviderDescriptor);
}
// Add new test service(s)
services.AddScoped<IEmailProvider, TestEmailProvider>();
services.AddSingleton<TestEmailServer>(); // May need to remove using the descriptor similar to IEmailProvider
// Remove the app's GrabGoContext registration, add in memory one then seed data.
var dbDescriptor = services.SingleOrDefault(d => d.ServiceType == typeof(DbContextOptions<GrabGoContext>));
if (dbDescriptor != null)
{
services.Remove(dbDescriptor);
}
services.AddDbContext<GrabGoContext>(options =>
{
options.UseInMemoryDatabase("InMemoryDbForTesting");
});
var serviceProvider = services.BuildServiceProvider();
using var scope = serviceProvider.CreateScope();
var scopedServices = scope.ServiceProvider;
var grabGoContext = scopedServices.GetRequiredService<GrabGoContext>();
// Seed your db here & save..
grabGoContext.SaveChanges();
});
base.ConfigureWebHost(builder);
}
}