我正在使用带有Autofac
的ASP.NET Core(2.0)和用于集成测试的Microsoft.AspNetCore.TestHost.TestServer
。但是,对于某些测试场景,我想注入一些服务模拟而不是ConfigureContainer
方法中加载的实现(如下所述:http://docs.autofac.org/en/latest/integration/aspnetcore.html#quick-start-with-configurecontainer)。
示例:
public class Program
{
public static void Main(string[] args)
{
var host = new WebHostBuilder()
.UseKestrel()
.ConfigureServices(s => s.AddAutofac())
.UseStartup<Startup>()
.Build();
host.Run();
}
}
public class Startup
{
...
public void ConfigureContainer(ContainerBuilder builder)
{
builder.RegisterModule(new Modules.ApiModule());
}
...
}
测试类:
public class BasicControllerTests
{
TestServer server;
HttpClient client;
public BasicControllerTests()
{
var resellerRepo = new Mock<IResellerProvider>();
resellerRepo.Setup(a => a.Query())
.Returns(new[] {
new Model.Reseller
{
Id = Guid.NewGuid(),
Code = "R1",
Name = "Reseller 1"
}
}.AsQueryable());
// How to inject mock properly in the lines below?
server = new TestServer(new WebHostBuilder()
.ConfigureServices(a => a.AddAutofac())
.UseStartup<Startup>());
client = server.CreateClient();
}
...
我想要做的是将TestServer
与所有依赖项一起使用,但只是在测试示例中模拟IResellerProvider
。实现这一目标的最佳方法是什么?当然,我可以为这个确切的案例创建一个TestStartup
类,但我想知道处理这种情况的正确方法是什么。
答案 0 :(得分:0)
我发现了一个很好的解决方法,可以让您在.net核心api中注入任何其他依赖项。 您将具有此标准代码以在测试中启动
var clientFactory = new WebApplicationFactory<Startup>();
var client = clientFactory.WithWebHostBuilder(builder =>
builder.ConfigureTestServices(services =>
{
}));
var _httpClient = client.CreateClient();
现在您需要将一个Action传递给.ConfigureTestServices,您可以使用它来删除常规应用启动时的注册,并添加另一个可以说是假的注册。这可能是因为如果您使用调试器在服务上,您将看到所有已注册的服务都已存在,并且只需要替换您想要的服务即可。这是我使用的一个简单示例
RemoveVehicleServiceRegistrationFrom(services);
services.AddScoped<IVehicleService, FakeVehicleService>();
在Remove方法中,您只需要查找并删除旧的注册即可。
private static void RemoveVehicleServiceRegistrationFrom(IServiceCollection services)
{
var vehicleService = services.Single(x => x.ServiceType == typeof(IVehicleService));
services.Remove(vehicleService);
}
最终版本如下
private HttpClient _httpClient;
[OneTimeSetUp]
public void Setup()
{
var clientFactory = new WebApplicationFactory<Startup>();
var client = clientFactory.WithWebHostBuilder(builder =>
builder.ConfigureTestServices(services =>
{
RemoveVehicleServiceRegistrationFrom(services);
services.AddScoped<IVehicleService, FakeVehicleService>();
}));
var _httpClient = client.CreateClient();
}
private static void RemoveVehicleServiceRegistrationFrom(IServiceCollection services)
{
var vehicleService = services.Single(x => x.ServiceType == typeof(IVehicleService));
services.Remove(vehicleService);
}