集成测试:固定装置多于自动装置

本文探讨了固定装置(fixture)在单元测试与集成测试中的应用,通过AutoFixture和IntegrationFixture简化测试过程,减少样板代码,提高测试效率。

目录

介绍

背景

使用代码

兴趣点


介绍

已显示在AutoFixture使用的固定装置(fixture)对于测试自动化是一个非常有用的概念。固定装置(fixture)不仅对单元测试有用,而且该概念也可以在集成测试中重用。在本文中,将解释什么是固定装置(fixture),以及该概念如何用于单元测试和集成测试。固定装置(fixture)总是有一个共同点:它们为您管理测试的安排部分,这不仅对单元测试,而且对所有类型的测试都是有用的。

背景

您对.NET Core应用程序的TDD有一定的经验,这将非常有帮助,其中包括模拟,最好是此处使用的.NET Core 3.1。拥有固定装置(fixture)的经验也很有用,但不是必需的。本文中显示的示例基于xUnit,但是概念和技术也可以应用于其他单元测试框架。

使用代码

首先,我们看一下要测试的代码。这里是:

[Route("api/[controller]")]
[ApiController]
public class SearchEngineController : ControllerBase
{
   private readonly ISearchEngineService _searchEngineService;

   public SearchEngineController(ISearchEngineService searchEngineService)
   {
       _searchEngineService = searchEngineService;
   }

   [HttpGet("{queryEntry}", Name = "GetNumberOfCharacters")]
   public async Task<ActionResult<int>> GetNumberOfCharacters(string queryEntry)
   {
       var numberOfCharacters = 
           await _searchEngineService.GetNumberOfCharactersFromSearchQuery(queryEntry);
       return Ok(numberOfCharacters);
   }
}

从上面的代码中可以清楚地看出,它只是一个控制器方法,它调用某些接口方法并返回带有OK状态码(200)的结果。这是该接口的实现。

public class SearchEngineService : ISearchEngineService
{
   private readonly HttpClient _httpClient;

   public SearchEngineService(HttpClient httpClient)
   {
       _httpClient = httpClient;
   }

   public async Task<int> GetNumberOfCharactersFromSearchQuery(string toSearchFor)
   {
       var result = await _httpClient.GetAsync($"/search?q={toSearchFor}");
       var content = await result.Content.ReadAsStringAsync();
       return content.Length;
   }
}

此代码也非常简单。Web请求完成,并返回结果的长度。

这是在Startup类中添加依赖项的方式:

public void ConfigureServices(IServiceCollection services)
{
   services.AddControllers();
   var googleLocation = Configuration["Google"];
   services.AddHttpClient<ISearchEngineService, SearchEngineService>(c =>
            c.BaseAddress = new Uri(googleLocation))
            .SetHandlerLifetime(TimeSpan.FromMinutes(5))
            .AddPolicyHandler(GetRetryPolicy());
}

现在清楚的是,我们需要能够模拟两个依赖关系:

  • 内部依赖项:这是ISearchEngineService的实例注入控制器。
  • 外部依赖项:这是设置为添加HttpClient内容基址的搜索引擎(url)。对于集成测试,我们需要模拟一下,因为我们对其是否给出相同的响应并保持在线状态没有任何影响。

内部依赖项的模拟通常是出于单元测试的目的,使用Moq可以如本文所述。外部依赖项的模拟通常是出于集成测试目的而进行的,如本文所述,使用WireMock ,此处提供的一些代码来自此。此处显示的所有代码在GitHub也可用。

这是使用固定装置(fixture)进行单元测试的样子:

[Fact]
public async Task GetTest()
{
   // arrange
   var fixture = new Fixture().Customize(new AutoMoqCustomization());
   var service = fixture.Freeze<Mock<ISearchEngineService>>();
   service.Setup(a => a.GetNumberOfCharactersFromSearchQuery(It.IsNotNull<string>()))
                .ReturnsAsync(8);
   var controller = fixture.Build<SearchEngineController>().OmitAutoProperties().Create();

   // act
   var response = await controller.GetNumberOfCharacters("Hoi");

   // assert
   Assert.Equal(8, ((OkObjectResult)response.Result).Value);
   service.Verify(s => s.GetNumberOfCharactersFromSearchQuery("Hoi"), Times.Once);
}

我们在这里看到的是以下内容:

  1. 第一步是创建固定装置。
  2. 之后, 调用Freeze方法(在Create方法之前)以指定内部依赖性,我们希望在测试结束时进行一些验证。
  3. 内部依赖关系需要与Setup方法一起设置。
  4. 在测试方法的assert部分中,我们验证对内部依赖项(service实例)的调用

如测试的实现,需要一个NuGet包:AutoFixture.AutoMoq

.NET Core的最新版本开始,集成测试变得更加容易。与单元测试的主要区别在于集成更加真实(因此配置性更差)。在Startup类和Program类都包括在内。使用实际的内部依赖关系来代替模拟/存根(stubs)。只有外部依赖项需要模拟,因为它们可以脱机,具有变化的行为或不稳定,所有这些都不应破坏测试。这是使用固定装置(fixture)进行集成测试的方法:

[Fact]
public async Task GetTest()
{
   // arrange
   using (var fixture = new Fixture<Startup>())
   {
      using (var mockServer = fixture.FreezeServer("Google"))
      {
          SetupStableServer(mockServer, "Response");
          var controller = fixture.Create<SearchEngineController>();

          // act
          var response = await controller.GetNumberOfCharacters("Hoi");

          // assert
          var request = mockServer.LogEntries.Select(a => a.RequestMessage).Single();
          Assert.Contains("Hoi", request.RawQuery);
          Assert.Equal(8, ((OkObjectResult)response.Result).Value);
       }
    }
}

private void SetupStableServer(FluentMockServer fluentMockServer, string response)
{
    fluentMockServer.Given(Request.Create().UsingGet())
    .RespondWith(Response.Create().WithBody(response, encoding: Encoding.UTF8)
    .WithStatusCode(HttpStatusCode.OK));
}

我们在这里看到的是类似的:

  1. 第一步是使用Startup类创建固定装置(fixture),一旦Create方法被调用,它就初始化所有依赖项。
  2. 之后,调用FreezeServer方法(在该Create方法之前)以设置外部依赖关系,我们希望在测试结束时进行一些验证。
  3. 内部依赖性需要使用一种自写SetupStableServer方法来设置,该方法描述某个请求需要某个响应。这将在此处更详细地说明。
  4. 在测试方法的assert部分中,我们验证发送到外部依赖项(模拟服务)的Web请求

实现诸如测试,需要另一个NuGet包:ConnectingApps.IntegrationFixture

从上面的代码可以清楚地看到,使用固定装置(fixture)进行集成测试的方式与使用固定装置(fixture)进行单元测试的方式基本相同。但是,除了安排和验证内部依赖项外,还需要使用外部依赖项来完成。他的建议听起来很明显,但是在不使用夹具的情况下进行集成测试时,需要大量的样板以作解释

兴趣点

在研究固定装置(fixture),使用固定装置(fixture)并撰写本文时,对我来说清楚的是,固定装置(fixture)的概念可以以多种方式使用。AutoFixture在编写单元测试的安排部分时很有用,但其固定装置(fixture)也可用于其他类型测试的(安排部分)。它使我们作为开发人员不必编写大量样板代码。

内容概要:本文围绕“基于需求侧响应的配电网供电能力综合评估”展开研究,重点探讨了价格型需求响应机制对配电网供电能力的影响,并提出了一套科学的综合评估方法。研究构建了一个涵盖一次设备安全、负荷平稳性、电能质量和系统效率等多个维度的评价指标体系,采用熵权法客观确定各指标权重,并结合模糊综合评价模型实现双层评分机制,从而定量评估不同运行场景下配电网的承载能力。通过Python编程实现算法仿真,利用算例分析验证了所提模型在不同分布式能源渗透率及多种需求响应策略下的有效性与灵敏度,揭示了价格激励措施在提升电网承载力方面的积极作用,为现代配电网的规划、调度与运行优化提供了理论依据和技术支撑。; 适合人群:具备一定电力系统基础知识和Python编程能力,从事电力系统规划、运行优化、需求响应等相关领域的科研人员及研究生。; 使用场景及目标:①评估高比例电动汽车、分布式电源接入背景下配电网的实际供电能力;②分析价格型需求响应策略对提升电网承载力的作用效果;③为配电网扩容改造、运行调度和需求管理政策制定提供决策支持; 阅读建议:建议读者结合文中提供的Python代码进行实证复现,重点关注熵权法与模糊综合评价的实现逻辑,并尝试修改参数设置以观察评估结果的变化趋势,加深对模型机理的理解。
源码下载地址: https://pan.quark.cn/s/a4b39357ea24 在Qt应用程序开发过程中,有时我们可能需要构建一个具备特殊视觉效果的窗口,例如设计成没有边框但带有阴影,并且依然允许用户拖动窗口。此类需求通常出现在构建简洁用户界面或定制化窗口外观的场景中。标题“Qt(部分)无边框窗口 边框阴影,可以拖动边框,移动窗口”所涵盖的技术要点主要集中于如何在Qt框架内达成这样的功能,尤其是借助winEvent函数的重写来应对特定的Windows平台事件。 让我们深入理解无边框窗口的概念。在Qt环境中,可以通过调整窗口的边框样式来构建无边框窗口。这通常是通过`setWindowFlags()`函数完成的,将`Qt::FramelessWindowHint`标志整合到窗口的标志参数里。例如: ```cpp setWindowFlags(Qt::CustomizeWindowHint | Qt::Window | Qt::FramelessWindowHint); ``` 这样一来,窗口将丧失标准的边框和标题栏,但依然维持着窗口管理的基本功能,例如最大化、最小化和关闭操作,前提是你也没有移除这些相关标志。 接下来,为了给无边框窗口增添阴影效果,可以利用Qt的QGraphicsDropShadowEffect类。首先创建一个QGraphicsView对象作为窗口的底层容器,然后在其上放置一个QGraphicsProxyWidget用以展示实际的窗口内容。接着,为QGraphicsView施加阴影效果: ```cpp QGraphicsDropShadowEffect *shadow = new QGraphicsDropShadowEffe...
内容概要:本文系统研究了同步电机与构网型变流器在电力系统中的频率稳定特性及其多时间尺度交互机理,基于Simulink搭建高保真仿真模型,深入分析两类电源在动态响应、惯量支撑、频率调节能力等方面的差异与耦合关系。研究涵盖不同运行工况下的频率波动响应特性,重点揭示控制延迟、电气与机械动态过程之间的时间尺度耦合机制,探讨构网型变流器在高比例新能源接入背景下对传统同步机主导系统的频率稳定性的影响,评估其替代或协同传统同步机的潜力与挑战,为未来电力系统的稳定运行与控制策略设计提供理论依据和技术支撑。; 适合人群:具备电力系统分析、自动控制理论及新能源并网技术背景的科研人员、高校研究生及电力工程技术人员;熟悉Simulink仿真环境者更佳; 使用场景及目标:①深入理解同步电机与构网型变流器在频率响应特性上的本质差异及其相互作用机理;②支撑高电力电子化电网的频率稳定性分析与新型控制器设计;③为多类型电源协同控制策略的研发与仿真验证提供模型基础与分析平台; 阅读建议:建议结合Simulink仿真模型进行同步操作,重点关注不同时间尺度动态过程的建模方法与参数敏感性分析,深入探究频率稳定性的内在机理,全面把握构网型控制在提升系统稳定性方面的优势与潜在局限。
代码转载自:https://pan.quark.cn/s/db56051ee6da 依据所提供的文档资料,能够归纳出以下与“寻求一个字符串中连续出现频率最高的子串”相关的基础知识: ### 一、问题的阐述与剖析 #### 1.1 问题背景 在计算机科学领域中,字符串操作是一项普遍且关键的工作。本议题聚焦于给定字符串,识别其中连续出现频率最高的子串。 #### 1.2 问题陈述 假定存在一个输入字符串 `str`,目标在于找出该字符串中出现频率最高的一个或多个连续子串,并统计它们的出现频次。 #### 1.3 输入输出格式 - **输入**:一个字符串 `str`。 - **输出**:连续出现频率最高的子串及其对应的出现次数。 ### 二、算法的构思与执行 #### 2.1 基本理念 遍历字符串的所有可能子串,并借助某种数据结构来追踪每个子串的出现频次。通过对比所有子串的出现频次,从而识别出出现频次最高的子串。 #### 2.2 具体执行步骤 1. **初始化**:设定一个字符串 `str` 来存储输入的字符串,以及一个辅助变量 `tep` 来暂存当前子串。 2. **外层循环**:从字符串长度减去1至1的逆向遍历,每次循环的 `i` 代表子串的长度。 3. **内层循环**:从0至字符串长度减去当前子串长度的遍历,每次循环的 `j` 指示子串的起始位置。 4. **子串提取**:运用 `substr` 方法从位置 `j` 开始截取长度为 `i` 的子串并存储至 `tep` 中。 5. **子串检测**:借助 `find` 和 `rfind` 方法分别确定子串在字符串中的初始出现位置 `t` 与最终出现位置 `num`。 6. **判定条件**:若 `t` 与...
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值