Внедрить сервисы в тесты xunit - PullRequest
0 голосов
/ 19 апреля 2019

Как я могу получить копию базы данных в памяти, которую я предоставляю тестируемому приложению?

Я хотел бы иметь возможность проверить, что контроллеры, имеющие побочные эффекты, действительно имеют эти эффекты. Например: 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

...