Gre*_*uff 17 c# integration-testing entity-framework-core xunit2 asp.net-core
我正在按照本教程
使用Entity Framework Core和SQL Server进行集成测试
我的代码看起来像这样
集成测试类
public class ControllerRequestsShould : IDisposable
{
private readonly TestServer _server;
private readonly HttpClient _client;
private readonly YourContext _context;
public ControllerRequestsShould()
{
// Arrange
var serviceProvider = new ServiceCollection()
.AddEntityFrameworkSqlServer()
.BuildServiceProvider();
var builder = new DbContextOptionsBuilder<YourContext>();
builder.UseSqlServer($"Server=(localdb)\\mssqllocaldb;Database=your_db_{Guid.NewGuid()};Trusted_Connection=True;MultipleActiveResultSets=true")
.UseInternalServiceProvider(serviceProvider);
_context = new YourContext(builder.Options);
_context.Database.Migrate();
_server = new TestServer(new WebHostBuilder()
.UseStartup<Startup>()
.UseEnvironment(Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT")));
_client = _server.CreateClient();
}
[Fact]
public async Task ReturnListOfObjectDtos()
{
// Arrange database data
_context.ObjectDbSet.Add(new ObjectEntity{ Id = 1, Code = "PTF0001", Name = "Portfolio One" });
_context.ObjectDbSet.Add(new ObjectEntity{ Id = 2, Code = "PTF0002", Name = "Portfolio Two" });
// Act
var response = await _client.GetAsync("/api/route");
response.EnsureSuccessStatusCode();
// Assert
var result = Assert.IsType<OkResult>(response);
}
public void Dispose()
{
_context.Dispose();
}
Run Code Online (Sandbox Code Playgroud)
据我了解,该.UseStartUp方法确保TestServer使用我的启动类
我遇到的问题是,当我的法案声明被发现时
var response = await _client.GetAsync("/api/route");
Run Code Online (Sandbox Code Playgroud)
我的启动类中出现连接字符串为空的错误.我认为我对这个问题的理解是,当我的控制器被客户端命中时,它会注入我的数据存储库,而数据存储库又会注入数据库上下文.
我想我需要将服务配置为该部分的一部分,new WebHostBuilder以便它使用在测试中创建的上下文.但我不知道该怎么做.
Startup.cs中的ConfigureServices方法
public void ConfigureServices(IServiceCollection services)
{
// Add framework services
services.AddMvc(setupAction =>
{
setupAction.ReturnHttpNotAcceptable = true;
setupAction.OutputFormatters.Add(new XmlDataContractSerializerOutputFormatter());
setupAction.InputFormatters.Add(new XmlDataContractSerializerInputFormatter());
});
// Db context configuration
var connectionString = Configuration["ConnectionStrings:YourConnectionString"];
services.AddDbContext<YourContext>(options => options.UseSqlServer(connectionString));
// Register services for dependency injection
services.AddScoped<IYourRepository, YourRepository>();
}
Run Code Online (Sandbox Code Playgroud)
lil*_*cob 22
@ ilya-chumakov的答案很棒.我只想补充一个选项
3.使用WebHostBuilderExtensions中的ConfigureTestServices方法.
方法ConfigureTestServices在Microsoft.AspNetCore.TestHost版本2.1中可用(在20.05.2018,它是RC1-final).它让我们可以用模拟覆盖现有的注册.
代码:
_server = new TestServer(new WebHostBuilder()
.UseStartup<Startup>()
.ConfigureTestServices(services =>
{
services.AddTransient<IFooService, MockService>();
})
);
Run Code Online (Sandbox Code Playgroud)
Ily*_*kov 21
WebHostBuilder.ConfigureServices过了一段时间,我认为最简单的解决方案是WebHostBuilder.ConfigureServices一起使用WebHostBuilder.UseStartup<T>来覆盖和模拟Web应用程序的DI注册:
_server = new TestServer(new WebHostBuilder()
.ConfigureServices(services =>
{
services.AddScoped<IFooService, MockService>();
})
.UseStartup<Startup>()
);
public class Startup
{
public void ConfigureServices(IServiceCollection services)
{
//use TryAdd to support mocking IFooService
services.TryAddTransient<IFooService, FooService>();
}
}
Run Code Online (Sandbox Code Playgroud)
这里的关键是使用类中的TryAdd方法Startup.在原作之前WebHostBuilder.ConfigureServices调用,所以首先注册你的模拟.如果使用,则跳过实际服务的注册.StartupTryAdd
更多信息:运行ASP.NET核心应用程序的集成测试.
创建TestStartup类以重新配置ASP.NET Core DI.您可以从中继承它Startup并仅覆盖所需的方法:
public class TestStartup : Startup
{
public TestStartup(IHostingEnvironment env) : base(env) { }
public override void ConfigureServices(IServiceCollection services)
{
//mock DbContext and any other dependencies here
}
}
Run Code Online (Sandbox Code Playgroud)
或者TestStartup可以从头开始创建以保持测试更清洁.
并指定它UseStartup来运行测试服务器:
_server = new TestServer(new WebHostBuilder().UseStartup<TestStartup>());
Run Code Online (Sandbox Code Playgroud)
Сomplete大型示例:使用内存数据库集成测试您的asp .net核心应用程序.
| 归档时间: |
|
| 查看次数: |
6682 次 |
| 最近记录: |