Я хочу использовать базу данных InMemory для тестирования моего веб-API с помощью WebApplicationFactory.
В моем тесте я хочу настроить данные в моем dbcontext, вызвать мой API, протестировать данные.
Это прекрасно работает с получением данных или созданием новых записей, но при обновлении контекст не обновляется, он по-прежнему содержит старую копию данных.
Мой DbContext инициализируется с InMemoryDatabaseRoot как предложено здесь .
Вот мой WebApplicationFactory
public class InMemDbWebApplicationFactory : WebApplicationFactory<Startup>
{
public static readonly InMemoryDatabaseRoot InMemoryDatabaseRoot = new InMemoryDatabaseRoot();
public ServiceProvider ServiceProvider { get; private set; }
protected override void ConfigureWebHost(IWebHostBuilder builder)
{
builder.ConfigureServices(services =>
{
var serviceProvider = new ServiceCollection()
.AddEntityFrameworkInMemoryDatabase()
.BuildServiceProvider();
services.AddDbContext<TestDbContext>(options =>
{
options.UseInMemoryDatabase("InMemoryDb", InMemoryDatabaseRoot);
options.UseInternalServiceProvider(serviceProvider);
});
ServiceProvider = services.BuildServiceProvider();
});
}
}
Мой тестовый класс использует его как IClassFixture, поэтому он используется всеми моими тестами.
Вот мой провальный тест
[Fact]
public async void TestPutBook()
{
using (var scope = _serviceProvider.CreateScope())
using (var context = scope.ServiceProvider.GetRequiredService<TestDbContext>())
{
var book1 = new Book { Name = "Book1" };
var book2 = new Book { Name = "Book2" };
context.Books.AddRange(book1, book2);
context.SaveChanges();
var updateResp = await _httpClient.PutAsJsonAsync($"/api/books/{book1.Id}", "Book1Update");
updateResp.EnsureSuccessStatusCode();
var getResp = await _httpClient.GetAsync($"/api/books/{book1.Id}");
getResp.EnsureSuccessStatusCode();
var stringResponse = await getResp.Content.ReadAsStringAsync();
book1 = JsonConvert.DeserializeObject<Book>(stringResponse);
Assert.NotNull(book1);
//this works
Assert.Equal("Book1Update", book1.Name);
book1 = context.Books.Find(book1.Id);
Assert.NotNull(book1);
//this fails book1.Name is still equal to "Book1"
Assert.Equal("Book1Update", book1.Name);
}
}
Я также попытался получить новый DbContext в той же области видимости, но затем он потерпел неудачу, говоря, что DbContext уже удален.
Вы можете найти полное тестовое решение здесь .