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); } }
  • 相关阅读:
    求二叉树中最远两节点距离
    计算机系统
    webdriver高级应用- 无人工干预地自动下载某个文件
    webdriver高级应用- 改变一个页面对象的属性值
    webdriver高级应用- 在ajax方式产生的浮动框中,单击选择包含某个关键字的选项
    webdriver高级应用-js操作滚动条
    webdriver高级应用-使用JavaScript操作页面元素
    Selenium WebDriver- 指定页面加载时间
    Selenium WebDriver- 操作浏览器的cookie
    Selenium WebDriver- 操作JavaScript的prompt弹窗(使用率低)
  • 原文地址:https://www.cnblogs.com/dudu/p/8227962.html
Copyright © 2011-2022 走看看