Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/asp.net-core/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何使用WebApplicationFactory在TestServer中切换服务?_C#_Asp.net Core_Xunit - Fatal编程技术网

C# 如何使用WebApplicationFactory在TestServer中切换服务?

C# 如何使用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

我正在使用自定义WebApplication factory

公共类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);
    }
}