簡體   English   中英

Xunit 測試 EFcore 存儲庫 InMemory DB

[英]Xunit Testing EFcore Repositories InMemory DB

我正在嘗試對存儲庫進行單元測試,我在 EFCore 中使用 InMemory 選項。 這是方法

    [Fact]
    public async Task GetCartsAsync_Returns_CartDetail()
    {
        ICartRepository sut = GetInMemoryCartRepository();
        CartDetail cartdetail = new CartDetail()
        {
            CommercialServiceName = "AAA"
        };

        bool saved = await sut.SaveCartDetail(cartdetail);

        //Assert  
        Assert.True(saved);
        //Assert.Equal("AAA", CartDetail[0].CommercialServiceName);
        //Assert.Equal("BBB", CartDetail[1].CommercialServiceName);
        //Assert.Equal("ZZZ", CartDetail[2].CommercialServiceName);
    }


    private ICartRepository GetInMemoryCartRepository()
    {
        DbContextOptions<SostContext> options;
        var builder = new DbContextOptionsBuilder<SostContext>();
        builder.UseInMemoryDatabase($"database{Guid.NewGuid()}");
        options = builder.Options;
        SostContext personDataContext = new SostContext(options);
        personDataContext.Database.EnsureDeleted();
        personDataContext.Database.EnsureCreated();
        return new CartRepository(personDataContext);
    }

我收到錯誤消息

   System.TypeLoadException : Method 'ApplyServices' in type 
   'Microsoft.EntityFrameworkCore.Infrastructure.Internal.InMemoryOptionsExtension' from assembly 
   'Microsoft.EntityFrameworkCore.InMemory, Version=1.0.1.0, Culture=neutral, 
   PublicKeyToken=adb9793829ddae60' does not have an implementation.


   Microsoft. 
  EntityFrameworkCore.InMemoryDbContextOptionsExtensions.UseInMemoryDatabase(DbContextOptionsBuilder 
   optionsBuilder, String databaseName, Action`1 inMemoryOptionsAction)


    Microsoft.EntityFrameworkCore.InMemoryDbContextOptionsExtensions.UseInMemoryDatabase[TContext] 
   (DbContextOptionsBuilder`1 optionsBuilder, String databaseName, Action`1 inMemoryOptionsAction)

我的參考來自https://www.carlrippon.com/testing-ef-core-repositories-with-xunit-and-an-in-memory-db/

請建議我當前的實施哪里出了問題。 提前致謝

我建議閱讀有關集成測試的官方 Microsoft 文檔。

https://docs.microsoft.com/fr-fr/aspnet/core/test/integration-tests?view=aspnetcore-3.0

其次,我開始添加這種樣板來使用 memory 數據庫創建測試,你很快就會停止這樣做。

對於集成測試,您應該靠近您的開發配置。

這是我的配置文件和我的 CustomerController 中的用法:

集成啟動文件

都考慮過數據庫創建和依賴注入

public class IntegrationStartup : Startup
    {
        public IntegrationStartup(IConfiguration configuration) : base(configuration)
        {
            Configuration = configuration;
        }

        public IConfiguration Configuration { get; }

        // This method gets called by the runtime. Use this method to add services to the container.
        public override void ConfigureServices(IServiceCollection services)
        {
            services.AddEntityFrameworkInMemoryDatabase().BuildServiceProvider();

            services.AddDbContext<StreetJobContext>(options =>
            {
                options.UseInMemoryDatabase("InMemoryAppDb");
            });


            //services.InjectServices();
            //here you can set your ICartRepository DI configuration


            services.AddMvc(option => option.EnableEndpointRouting = false)
                .SetCompatibilityVersion(CompatibilityVersion.Version_3_0)
                .AddApplicationPart(Assembly.Load(new AssemblyName("StreetJob.WebApp")));

            ConfigureAuthentication(services);
        }

        // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
        public override void Configure(IApplicationBuilder app, IWebHostEnvironment env)
        {
            var serviceScopeFactory = app.ApplicationServices.GetRequiredService<IServiceScopeFactory>();
            using (var serviceScope = serviceScopeFactory.CreateScope())
            {
                //Here you can add some data configuration
            }

            app.UseMvc();
        }

虛假的啟動

它與 Microsoft 文檔中的非常相似

public class CustomWebApplicationFactory<TStartup> : WebApplicationFactory<TStartup> where TStartup : class
{
    protected override IWebHostBuilder CreateWebHostBuilder()
    {
        return WebHost.CreateDefaultBuilder(null)
            .UseStartup<TStartup>();
    }

    protected override void ConfigureWebHost(IWebHostBuilder builder)
    {
        builder.UseSolutionRelativeContentRoot(Directory.GetCurrentDirectory());

        builder.ConfigureAppConfiguration(config =>
        {
            config.AddConfiguration(new ConfigurationBuilder()
               //custom setting file in the test project
                .AddJsonFile($"integrationsettings.json")
                .Build());
        });

        builder.ConfigureServices(services =>
        {
        });
    }
}

controller

public class CustomerControllerTest : IClassFixture<CustomWebApplicationFactory<IntegrationStartup>>
    {
        private readonly HttpClient _client;
        private readonly CustomWebApplicationFactory<IntegrationStartup> _factory;
        private readonly CustomerControllerInitialization _customerControllerInitialization;
        public CustomerControllerTest(CustomWebApplicationFactory<IntegrationStartup> factory)
        {
            _factory = factory;
            _client = _factory.CreateClient();
        }
}

使用這種設置,測試集成測試與開發 controller 非常相似。 對於 TDD 開發人員來說,這是一個相當不錯的配置。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM