Sii*_*aas 6 c# testing autofac asp.net-core
我想为我的Asp .net核心应用程序编写集成测试,但我不希望我的测试使用某些服务的真实实现。
public class Startup
{
public void ConfigureServices(IServiceCollection services)
{
...
services.AddTransient<IExternalService,ExternalService>();
...
}
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
...
}
}
public interface IExternalService
{
bool Verify(int id);
}
public class ExternalService : IExternalService
{
public bool Verify(int id)
{
//Implemetation is here.
//I want to fake this implemetation during testing.
}
}
[Fact]
public void TestCase()
{
//Stub out service
var myExtService = new Mock<IExternalService>();
//Setup response by stub
myExtService
.Setup(p => p.Verify(It.IsAny<int>()))
.Returns(false);
var host = new WebHostBuilder()
.UseStartup<Startup>()
.ConfigureServices((services) =>
{
//Setup injection
services.AddTransient<IExternalService>((a) =>
{
return myExtService.Object;
});
});
var server = new TestServer(host);
var client = server.CreateClient();
var response = client.GetAsync("/").Result;
var responseString = response.Content.ReadAsStringAsync().Result;
Assert.Contains("Your service returned: False", responseString);
}
Run Code Online (Sandbox Code Playgroud)
测试案例中的当前注入设置不起作用,因为ExternalService是通过模拟注入的。
但是,当我services.AddTransient<IExternalService,ExternalService>;从中删除时,测试将通过Startup。
很有可能Startup稍后会调用一个in ,并且该类中的所有设置都被应用程序首选。
在测试中设置某些依赖项时,我必须使用哪些选项,但要使用其他所有声明项Startup?
更新
您唯一需要更改的是使用ConfigureTestServices而不是ConfigureServices. ConfigureTestServices在您的之后运行Startup,因此您可以使用模拟/存根覆盖真正的实现。ConfigureServices较新的目的是用于此目的,相反,它配置“主机服务”,这些服务在应用程序的主机构建阶段使用,并复制到应用程序的 DI 容器中。
ConfigureTestServices在 ASP Core 2.1 及更高版本中可用。
var host = new WebHostBuilder()
.UseStartup<Startup>()
.ConfigureTestServices((services) =>
{
//Setup injection
services.AddTransient<IExternalService>((a) =>
{
return myExtService.Object;
});
});
Run Code Online (Sandbox Code Playgroud)
我所知道的唯一的选择是设置WebHostBuilder有UseEnvironment:
var host = new WebHostBuilder()
.UseStartup<Startup>()
.ConfigureServices(services =>
{
//Setup injection
services.AddTransient<IExternalService>(provider =>
{
return myExtService.Object;
});
})
.UseEnvironment("IntegrationTest");
Run Code Online (Sandbox Code Playgroud)
然后在ConfigureServices方法中添加条件Startup:
public void ConfigureServices(IServiceCollection services)
{
if (Configuration["Environment"] != "IntegrationTest")
{
services.AddTransient<IExternalService, ExternalService>();
}
services.AddMvc();
// ...
}
Run Code Online (Sandbox Code Playgroud)
我做了更多的探索,另一个选择是不使用UseStartup扩展方法而是WebHostBuilder直接配置。您可以通过多种方式执行此操作,但我认为您可以创建自己的扩展方法来在测试中创建模板:
public static class WebHostBuilderExt
{
public static WebHostBuilder ConfigureServicesTest(this WebHostBuilder @this, Action<IServiceCollection> configureServices)
{
@this.ConfigureServices(services =>
{
configureServices(services);
services.AddMvc();
})
.Configure(builder =>
{
builder.UseMvc();
});
return @this;
}
}
Run Code Online (Sandbox Code Playgroud)
现在你的测试可以像下面这样设置:
var host = new WebHostBuilder()
.ConfigureServicesTest(services =>
{
//Setup injection
services.AddTransient<IInternalService>(provider =>
{
return myExtService.Object;
});
});
var server = new TestServer(host);
Run Code Online (Sandbox Code Playgroud)
这意味着您必须显式设置容器将为您正在调用的特定端点解析的所有实现。您可以选择模拟或使用具体实现。
| 归档时间: |
|
| 查看次数: |
2872 次 |
| 最近记录: |