面向云技术架构 - 痴者工良

  • 首页
  • 工良写的电子书
    • kubernetes 教程
    • 从 C# 入门 Kafka
    • 多线程和异步
    • 动态编程-反射、特性、AOP
    • 表达式树
  • 本站文章导航
  • 隐私政策
愿有人陪你颠沛流离
遇到能让你付出的事物或者人,都是一种运气。
能遇到,就该珍惜。或许你们最终没能在一起,但你会切实地感受到力量。
正因为这样,那段相遇才变得有价值,才没有辜负这世间的每一段相遇。
  1. 首页
  2. .NET
  3. 正文

ASP.NET Core 集成测试

2022年3月30日 664点热度 0人点赞 0条评论
内容纲要

包:

Microsoft.AspNetCore.Mvc.Testing
Microsoft.AspNetCore.TestHost
Moq

集成测试可在包含应用支持基础结构(如数据库、文件系统和网络)的级别上确保应用组件功能正常。 ASP.NET Core 通过将单元测试框架与测试 Web 主机和内存中测试服务器结合使用来支持集成测试。

集成测试确认两个或更多应用组件一起工作以生成预期结果,可能包括完整处理请求所需的每个组件。

这些更广泛的测试用于测试应用的基础结构和整个框架,通常包括以下组件:

  • 数据库
  • 文件系统
  • 网络设备
  • 请求-响应管道
    单元测试使用称为 fake 或 mock 对象的制造组件,而不是基础结构组件。

与单元测试相比,集成测试:

  • 使用应用在生产环境中使用的实际组件。
  • 需要进行更多代码和数据处理。
  • 需要更长时间来运行。

基础结构组件(如测试 Web 主机和内存中测试服务器 (TestServer))由 TestServer 包提供或管理。 使用此包可简化测试创建和执行。

请勿为通过数据库和文件系统进行的数据和文件访问的每个可能排列编写集成测试。 无论应用中有多少位置与数据库和文件系统交互,一组集中式读取、写入、更新和删除集成测试通常能够充分测试数据库和文件系统组件。 将单元测试用于与这些组件交互的方法逻辑的例程测试。 在单元测试中,使用基础结构 fake/mock 会导致更快地执行测试。

Microsoft.AspNetCore.Mvc.Testing 包处理以下任务:

  • 将依赖项文件 (.deps) 从 SUT 复制到测试项目的 bin 目录中。

  • 将内容根目录设置为 SUT 的项目根目录,以便可在执行测试时找到静态文件和页面/视图。

  • 提供 WebApplicationFactory 类,以简化 SUT 在 中的启动过程。

快速创建一个 Web 服务器:

    public TestServer CreateServer()
    {
        var path = Assembly.GetAssembly(typeof(BasketScenarioBase))
            .Location;

        var hostBuilder = new WebHostBuilder()
            .UseContentRoot(Path.GetDirectoryName(path))
            .ConfigureAppConfiguration(cb =>
            {
                cb.AddJsonFile("appsettings.json", optional: false)
                .AddEnvironmentVariables();
            }).UseStartup<BasketTestsStartup>();

        return new TestServer(hostBuilder);
    }

接着是实际使用的 Startup,使用一个子类继承 Startup,再把它注入到 ASP.NET Core 中。

    class BasketTestsStartup : Startup
    {
        public BasketTestsStartup(IConfiguration env) : base(env)
        {
        }

        public override IServiceProvider ConfigureServices(IServiceCollection services)
        {
            services.Configure<RouteOptions>(Configuration);
            return base.ConfigureServices(services);
        }

        protected override void ConfigureAuth(IApplicationBuilder app)
        {
            if (Configuration["isTest"] == bool.TrueString.ToLowerInvariant())
            {
                app.UseMiddleware<AutoAuthorizeMiddleware>();
            }
            else
            {
                base.ConfigureAuth(app);
            }
        }
    }

然后通过创建 TestServer 服务器对象,再创建一个对应的客户端即可。

    [Fact]
    public async Task Post_basket_and_response_ok_status_code()
    {
        using (var server = CreateServer())
        {
            var content = new StringContent(BuildBasket(), UTF8Encoding.UTF8, "application/json");
            var response = await server.CreateClient()
                .PostAsync("url", content);     // url只需要填写 /api/xxx 不需要填写主机地址

            response.EnsureSuccessStatusCode();
        }
    }

这样便可以请求任一个 api 了。

另外还可以从 Web Host 中取出一个实例:

            using (var server = CreateServer())
            {
                var redis = server.Host.Services.GetRequiredService<ConnectionMultiplexer>();

                var redisBasketRepository = BuildBasketRepository(redis);

                var basket = await redisBasketRepository.UpdateBasketAsync(new CustomerBasket("customerId")
                {
                    BuyerId = "buyerId",
                    Items = BuildBasketItems()
                });

                Assert.NotNull(basket);
                Assert.Single(basket.Items);
            }

可以通过在主机生成器上调用 ConfigureTestServices,在测试中替代服务。 若要注入模拟服务,SUT 必须具有包含 Startup.ConfigureServices 方法的 类。

    // Arrange
    var client = _factory.WithWebHostBuilder(builder =>
        {
            builder.ConfigureTestServices(services =>
            {
                services.AddScoped<IQuoteService, TestQuoteService>();
            });
        })
        .CreateClient();

设置 Web Host 为开发环境或测试环境:

protected override IHostBuilder CreateHostBuilder() =>
    base.CreateHostBuilder()
        .ConfigureHostConfiguration(
            config => config.AddEnvironmentVariables("ASPNETCORE"));

// 如果 SUT 使用 Web 主机 (IWebHostBuilder),则替代 CreateWebHostBuilder:

protected override IWebHostBuilder CreateWebHostBuilder() =>
    base.CreateWebHostBuilder().UseEnvironment("Testing");

而在集成测试中,也可以很方便 配置加载的 appsettings.json、appsettings.development.json、appsettngs.production.json 文件。

        config.AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
              .AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true, reloadOnChange: true);
本作品采用 知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议 进行许可
标签: asp core net 单元测试
最后更新:2022年5月28日

痴者工良

高级程序员劝退师

点赞
< 上一篇
下一篇 >

文章评论

razz evil exclaim smile redface biggrin eek confused idea lol mad twisted rolleyes wink cool arrow neutral cry mrgreen drooling persevering
取消回复

COPYRIGHT © 2022 whuanle.cn. ALL RIGHTS RESERVED.

Theme Kratos Made By Seaton Jiang

粤ICP备18051778号

粤公网安备 44030902003257号