Как я могу получить копию базы данных в памяти, которую я предоставляю тестируемому приложению?
Я хотел бы иметь возможность проверить, что контроллеры, имеющие побочные эффекты, действительно имеют эти эффекты. Например: AddNewFoo?name=bar
.
Я хочу проверить, что Foo
с именем Bar
действительно было добавлено в базу данных.
Я следую вместе со статьей от Microsoft, размещенной внизу, в которой описывается настройка xunit с приложением .Net Core Asp MVC. В этой статье они переопределяют функциональность запуска MVC и дают вам возможность поменять сервисы на макеты. Большинство моих услуг одинаковы, потому что я действительно хочу протестировать эти услуги. Тем не менее, я пытаюсь заставить их пример с БД работать, и это по большей части, но я чувствую, что они опускают важную деталь. Они настраивают БД так:
services.AddDbContext<MyDbContext>(options =>
{
options.UseInMemoryDatabase("InMemoryDbForTesting");
options.UseInternalServiceProvider(serviceProvider);
});
// Build the service provider.
var sp = services.BuildServiceProvider();
// Create a scope to obtain a reference to the database
// context (ApplicationDbContext).
using (var scope = sp.CreateScope())
{
var scopedServices = scope.ServiceProvider;
var db = scopedServices.GetRequiredService<MyDbContext>();
db.Database.EnsureCreated();
// Seed the database with test data.
DbInitializer.InitializeDbForTests(db);
}
Это хорошо работает. Все мои тесты проходят для контроллеров без побочных эффектов, таких как GetFoos
. Однако для тестирования контроллеров, имеющих побочные эффекты, я бы хотел иметь возможность
public class FooTests : IClassFixture<CustomWebApplicationFactory<Startup>>
{
private readonly HttpClient _client;
public FooTests(CustomWebApplicationFactory<Startup> factory)
{
_client = factory.CreateClient(new WebApplicationFactoryClientOptions
{
AllowAutoRedirect = false
});
}
[Fact]
//http://localhost:5000/api/Foo/CreateFoo?name=bar
public async Task Foo_GetAllFoos_ReturnAtLeastOneFoo()
{
var request = new HttpRequestMessage(new HttpMethod("GET"),
"/api/Foo/CreateFoo?name=bar");
var response = await _client.SendAsync(request);
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
//Theoretical code I haven't written, yet
Assert.True(myDbContext.Foo.Any(x => x.name == "bar"));
Итак, вопрос в том, как мне получить соответствующий myDbContext.
Я пытался внедрить его, но IClassFixture<CustomWebApplicationFactory<Startup>>
мешает мне добавлять аргументы в конструктор. Даже если бы это было возможно, вероятно, не было бы инъекции зависимости.
https://docs.microsoft.com/en-us/aspnet/core/test/integration-tests?view=aspnetcore-2.2