【发布时间】:2021-04-15 22:15:36
【问题描述】:
我有一个标准的 ASP.Net Web API 项目,其数据库设置如下所示:
Startup.cs
services.AddDbContext<ProjectDbContext>(opts =>
opts.UseSqlServer(Configuration.GetConnectionString("ProjectDb")));
这按预期工作。
我还有一个集成测试设置,我尝试用内存中的连接替换 SQL Server 连接,以便在每次测试运行时保持干净:
ProjectWebApplicationFactory.cs
public class ProjectWebApplicationFactory : WebApplicationFactory<Startup> {
protected override void ConfigureWebHost(IWebHostBuilder builder) {
builder.ConfigureServices(services => {
var prodDb = services.SingleOrDefault(s => s.ServiceType == typeof(ProjectDbContext));
services.Remove(prodDb);
services.AddDbContext<ProjectDbContext>(opts => {
opts.UseInMemoryDatabase(Guid.NewGuid().ToString());
});
}
}
这在本地运行时再次正常工作。但是,当将此代码推送到构建/测试服务器时,它开始失败。初始 SQL Server 数据库上下文在被替换为内存版本之前尝试连接到数据库。由于服务器在本地可用,但在测试服务器上不可用,这会导致所有集成测试在无法运行之前就失败。
在运行集成测试时防止 SQL Server 上下文尝试连接的正确方法是什么?
【问题讨论】:
-
除非您需要,否则不要致电
UseSqlServer。至少,在选项操作中添加一个if块并添加您真正想要的提供程序。 -
应用程序的正常运行需要它。我不想唯一一次是在集成测试期间。在 Startup 类中没有
if。 -
所以添加一个
if,这仅在单元测试期间是正确的。或者根本不要在单元测试期间使用 Startup,在单元测试本身中创建一个 ServicesCollection 实例。AddDbContext接受一个动作。你可以写AddDbContext(opts=>{ if (...){opts.UseSqlServer...} else { opts.UseInMemory,而不是写AddDbContext(opts=>opts.Use....。这要容易得多。用你想要的配置创建一个ServiceCollection
标签: c# asp.net sql-server asp.net-web-api integration-testing