Mor*_*siu 4 c# xunit asp.net-core
我正在使用自定义 WebApplication 工厂
public class CustomWebApplicationFactory<TStartup> : WebApplicationFactory<TStartup> where TStartup: class {
protected override void ConfigureWebHost(IWebHostBuilder builder) {
builder.ConfigureServices(services => {
// Create a new service provider.
var serviceProvider = new ServiceCollection()
.AddEntityFrameworkInMemoryDatabase()
.BuildServiceProvider();
services.AddDbContext<GrabGoContext>(options => {
options.UseInMemoryDatabase("GrabGoDb");
options.UseInternalServiceProvider(serviceProvider);
});
services.AddSingleton<TestEmailServer>();
services.AddScoped<IEmailProvider, TestEmailProvider>(); // <- HERE
});
base.ConfigureWebHost(builder);
}
Run Code Online (Sandbox Code Playgroud)
我想将我IEmailProvider调用的默认服务切换DefaultEmailProvider为我的特殊服务TestEmailProvider,但问题是该方法ConfigureWebHost是在之前执行的Startup.ConfigureServices(IServiceCollection services),所以我的服务DefaultEmailProvider是在之后设置的TestEmailProvider。因此在我的ClientController服务中DeafultEmailProvider使用的是而不是测试服务。
我的问题是:
如何使用 WebApplicationFactory 切换DefaultEmailProvider服务TestEmailProvider?
@更新
好吧,我已经设法更深入了。我发现该方法builder.ConfigureTestServices()会覆盖其他服务。但是当在我的方法中切换它ConfigureWebHost(IWebHostBuilder builder)并且我尝试使用CreateClient()它创建新的 HttpClient 时,会抛出:
System.InvalidOperationException: 'A ConfigureServices method that returns an IServiceProvider is not compatible with the use of one or more IStartupConfigureServicesFilter. Use a void returning ConfigureServices method instead or a ConfigureContainer method.'
Run Code Online (Sandbox Code Playgroud)
@更新2019年5月28日
仍在寻找更好的解决方案,但我已经设法进行了某种破解。
在我的Startup.cs我已经交换了我的
services.AddScoped<IEmailProvider, SendGridEmailProvider>();
与 TryAdd[某事]
services.TryAddScoped<IEmailProvider, SendGridEmailProvider>();
您应该能够在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);
}
}
Run Code Online (Sandbox Code Playgroud)
您可能想让自己更轻松,只需实现工厂,就像上面一样,而不是保持通用。我还为您的内存数据库添加了略有不同的代码。
它尚未编译,但语法应该相差不远。希望有帮助。
| 归档时间: |
|
| 查看次数: |
3861 次 |
| 最近记录: |