zoukankan      html  css  js  c++  java
  • 体验 ASP.NET Core 集成测试三剑客:xUnit.net、TestServer、EF Core InMemory

    这是昨天解决的一个问题,针对一个 web api 的客户端代理类写集成测试,既要测试 web api,又要测试 web api 客户端。

    测试 web api,就要在运行测试时自动启动 web api 站点,asp.net core 中的 TestServer 就是为此而生,而且与 asp.net core 结合的天衣无缝,不仅自己可以通过I WebHostBuilder 配置站点,而且可以直接使用 web api 站点的 Startup 类。

    对于测试时的数据模拟,可以通过 EF Core 提供的 InMemory database ,使用起来超级简单,只需在依赖注入 DbContext 时使用 options.UseInMemoryDatabase() 。

    而对于 TestServer 的统一管理(配置、启动、销毁),对所测试的类的依赖注入,可以借助 xUnit.net 的 fixture class ,详见 Shared Context between Tests 。

    xUnit.net fixture class 的示例代码如下:

    public class WebApiTestFixture : IDisposable
    {
        private readonly TestServer _testServer;
    
        public WebApiTestFixture()
        {
            IWebHostBuilder webHostBuilder = WebHost.CreateDefaultBuilder()
                .ConfigureLogging((logging) =>
                {
                    logging.AddConsole();
                })
                .ConfigureServices(services =>
                {
                    services.AddSingleton<IMemcachedClient, NullMemcachedClient>();
                    services.AddDbContext<UCenterDbContext>(options =>
                    {
                        options.UseInMemoryDatabase("UCenter");
                    });
                })
                .UseStartup<Startup>();
    
            _testServer = new TestServer(webHostBuilder);
            ServerServices = _testServer.Host.Services;
            ProvisionData(ServerServices.GetRequiredService<UCenterDbContext>());
            ConfigureClientServices(_testServer.CreateClient());
        }
    
        public IServiceProvider ClientServices { get; private set; }
        public IServiceProvider ServerServices { get; private set; }
    
        private void ConfigureClientServices(HttpClient httpClient)
        {
            IServiceCollection services = new ServiceCollection();
            services.AddSingleton<IMemcachedClient, NullMemcachedClient>();
            services.AddLogging(builder => builder.AddConsole());
            services.AddSingleton(httpClient);
            services.AddSingleton<IUCenterService, UCenterService>();
            ClientServices = services.BuildServiceProvider();
        }
    
        private void ProvisionData(UCenterDbContext dbContext)
        {
            //dbContext.Add();            
            dbContext.SaveChanges();
        }
    
        public void Dispose()
        {
            _testServer.Dispose();
        }
    }

    集成测试的示例代码如下:

    public class UCenterServiceTests : IClassFixture<WebApiTestFixture>
    {
        private readonly IUCenterService _ucenterService;
        private readonly UCenterDbContext _dbContext;
    
        public UCenterServiceTests(WebApiTestFixture fixture)
        {
            _ucenterService = fixture.ClientServices.GetService<IUCenterService>();
            _dbContext = fixture.ServerServices.GetService<UCenterDbContext>();
        }
    
        [Fact]
        public async Task GetUserTest()
        {
            var fakeUser = _dbContext.Users.FirstOrDefault();

    var user = await _ucenterService.GetUser(u => u.DisplayName, fakeUser.DisplayName); user.ShouldNotBeNull(); user.BlogApp.ShouldBe(fakeUser.BlogApp); } }
  • 相关阅读:
    得不到的永远在骚动
    这些.NET开源项目你知道吗?让.NET开源来得更加猛烈些吧【转】
    Windows CMD命令大全【转】
    创业为什么选择北上广?
    为什么你还把时间浪费在无效人脉社交上?
    五步搞定Android开发环境部署——非常详细的Android开发环境搭建教程
    mysql分区操作
    程序员常用网站
    4种提升SQL查询性能的知识
    获得局域网内其他成员的信息
  • 原文地址:https://www.cnblogs.com/dudu/p/8227962.html
Copyright © 2011-2022 走看看