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); } }
  • 相关阅读:
    不知如何摧毁Kendo UI for jQuery小部件?这份指南不得不看
    MyEclipse导航代码第二弹,Java开发更便捷
    索引扫描与索引查找区别
    Chrome使用技巧
    什么是中台?所有的中台都是业务中台
    跨域资源共享CORS详解
    多线程之入门起步(三)
    聊天程序——基于Socket、Thread (二)
    多线程的相关概念(一)
    使用BCP实用工具导出导入数据
  • 原文地址:https://www.cnblogs.com/dudu/p/8227962.html
Copyright © 2011-2022 走看看