Интеграционные тесты xUnit в.NET Core выдают ошибку "Элемент с таким же ключом уже добавлен"

Я использую xUnit для выполнения интеграционных тестов в приложении.NET Core. Я следую за разделом интеграционных тестов этого поста. Он познакомил меня с TestFixture, которая размещает проект на сервере в памяти. Код запуска инициализирует базу данных в памяти с двумя записями в таблице активов. Тесты показаны ниже.

У меня проблема в том, что когда я запускаю эти тесты, они терпят неудачу с ошибкой: элемент с тем же ключом уже был добавлен

Я предполагаю, что это потому, что Автозагрузка пытается добавить те же две записи в базу данных для каждого теста. Если я запускаю тесты во второй раз, они проходят. Когда я запускаю их в третий раз, они терпят неудачу и чередуются вот так. Когда я помещаю точку останова в код Starup, который инициализирует базу данных, создается впечатление, что два потока пытаются выполнить строку останова, потому что когда я нажимаю F10, чтобы перейти к следующей строке, выполнение остается на той же строке. Как я могу подтвердить, что это проблема? Если это действительно так!

public class AssetControllerTests : IClassFixture<TestFixture<ManagementSystemCore.Startup>>
{
    private readonly HttpClient _client;

    public AssetControllerTests(TestFixture<ManagementSystemCore.Startup> fixture)
    {
        _client = fixture.Client;
    }

    private List<Asset> GetTestAssets()
    {
        return Startup.GetTestAssets();
    }

    [Fact]
    public async Task Assets_ReturnsAViewResult_WithListOfAssets()
    {
        // Arrange
        var mockRepo = new Mock<IAssetRepository>();
        mockRepo.Setup(repo => repo.ListAsync()).Returns(Task.FromResult(GetTestAssets()));

        try
        {
            var controller = new AssetController(mockRepo.Object);
            // Act
            var result = await controller.Assets();

            // Assert
            var viewResult = Assert.IsType<ViewResult>(result);
            var model = Assert.IsAssignableFrom<IEnumerable<AssetViewModel>>(viewResult.ViewData.Model);
            Assert.Equal(2, model.Count());
        }
        catch (Exception e)
        {
            var msg = e.Message;
        }
    }

    [Fact]
    public async Task Details_ReturnsViewResult_WithOneAsset()
    {
        // Arrange - get an asset known to exist
        var testAssets = Startup.GetTestAssets();
        var id = testAssets.Select(a => a.Id).First();

        // Act
        var response = await _client.GetAsync("/asset/details/" + id);

        // Assert
        response.EnsureSuccessStatusCode();
        var responseString = await response.Content.ReadAsStringAsync();
        Assert.True(responseString.Contains(testAssets.Select(a => a.SerialNumber).First()));
        Assert.True(responseString.Contains(testAssets.Select(a => a.PartNumber).First()));
    }        

    [Fact]
    public async Task PostAsync_ReturnsBadRequest_GivenNullModel()
    {
        // Arrange & Act
        var mockRepo = new Mock<IAssetRepository>();
        var controller = new AssetController(mockRepo.Object);
        controller.ModelState.AddModelError("error", "some error");

        // Act
        var result = await controller.PostAsync(null);

        // Assert
        Assert.IsType<BadRequestObjectResult>(result);
    }
}

Вот код запуска:

    public class Startup
{
    public Startup(IHostingEnvironment env)
    {
        var builder = new ConfigurationBuilder()
            .SetBasePath(env.ContentRootPath)
            .AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
            .AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true)
            .AddEnvironmentVariables();
        Configuration = builder.Build();
    }

    public IConfigurationRoot Configuration { get; }

    public void ConfigureServices(IServiceCollection services)
    {
        services.AddDbContext<AppDbContext>(options => options.UseInMemoryDatabase());

        services.AddMvc();
        services.AddScoped<ITodoRepository, TodoRepository>();
        services.AddScoped<IAssetRepository, AssetRepository>();
        services.AddScoped<IValuesRepository, ValuesRepository>();
    }

    public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
    {
        loggerFactory.AddConsole(Configuration.GetSection("Logging"));
        loggerFactory.AddDebug();

        if (env.IsDevelopment())
        {
            app.UseDeveloperExceptionPage();

            var repository = app.ApplicationServices.GetService<IAssetRepository>();

            InitializeDatabaseAsync(repository).Wait();
        }

        app.UseStaticFiles();

        app.UseMvc(routes =>
        {
            routes.MapRoute(
                name: "default",
                template: "{controller=Asset}/{action=Index}/{id?}");
        });
    }

    // Load the database with sample assets
    public async Task InitializeDatabaseAsync(IAssetRepository repo)
    {
        var assetList = await repo.ListAsync();
        if (!assetList.Any())
        {
            foreach (var asset in GetTestAssets())
            {
                await repo.AddAsync(asset);
            }
        }
    }

    public static List<Asset> GetTestAssets()
    {
        return new List<Asset>()
        {
            new Asset("5eb6eb60-72d7-4f51-b209-22a4d97604bd", "SN1234", "PN1234"),
            new Asset("4dc5fd59-98d7-3g34-c310-47g5e84987cg", "SN5678", "PN5678")
        };
    }
}

0 ответов

Другие вопросы по тегам