我正在为我的 API 编写集成测试。我决定使用内存数据库,但是我遇到了一些问题。
当我第一次运行测试时,一切都很顺利,我返回了 200Ok 结果。
当我重新运行测试时,测试失败,并且我意识到当我更改电子邮件时它会自行修复。
从那时起,我已经实现了正确的拆卸方法,因此它在测试结束时被销毁,但是我仍然不确定为什么数据仍然存在,即使每次创建
WebApplicationFactory
并且我有services.RemoveAll(typeof(AppDbContext));
在再次创建内存数据库之前执行?
另外,内存数据库不是应该只存在于内存中吗?为什么在测试完成并且我关闭了 Visual Studio 并关闭我的电脑后数据仍然存在?是否涉及某种缓存机制?
另外,我想指出我使用了
Dipose()
并正确处置,但问题仍然存在。
原代码如下:
public class IntegrationTest
{
protected readonly HttpClient _testClient;
private readonly WebApplicationFactory<Program> _appFactory;
protected IntegrationTest()
{
_appFactory = new WebApplicationFactory<Program>()
.WithWebHostBuilder(builder =>
{
builder.ConfigureServices(services =>
{
services.RemoveAll(typeof(AppDbContext));
services.AddDbContext<AppDbContext>(options =>
{
options.UseInMemoryDatabase("TestDb");
});
var serviceProvider = new ServiceCollection()
.AddEntityFrameworkInMemoryDatabase()
.BuildServiceProvider();
var sp = services.BuildServiceProvider();
using var scope = sp.CreateScope();
var scopedServices = scope.ServiceProvider;
var db = scopedServices.GetRequiredService<AppDbContext>();
db.Database.EnsureCreated();
});
});
_testClient = _appFactory.CreateClient();
}
protected async Task AuthenticateAsync()
{
_testClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("bearer", await GetBearerTokenAsync());
}
private async Task<string> GetBearerTokenAsync()
{
// Register user
var registerResponse = await _testClient.PostAsJsonAsync("/register", new
{
email = "[email protected]",
password = "Passw0rd."
});
registerResponse.EnsureSuccessStatusCode();
更改了导致问题的电子邮件值
在测试结束时实施适当的拆卸以销毁数据库
如果您使用像 MSTest 这样的测试框架,最好将初始化逻辑从类构造函数移动到
[TestInitialize]
带注释的方法,并在您处理 [TestCleanup]
的地方引入 _appFactory
带注释的方法。这样,每个测试用例都会有一个新的 _appFactory
实例。