SpringBoot 使用@WebMvcTest测试MVC Web Controller

目录
  • 依赖
  • Web 控制器的职责
  • 单元测试还是集成测试?
  • 使用 @WebMvcTest 验证控制器职责
  • @ExtendWith
  • 使用带或不带 controllers 参数的 @WebMvcTest?
    • 1.验证 HTTP 请求匹配
    • 2.验证输入序列化
    • 3.验证输入验证
    • 4.验证业务逻辑调用
    • 5.验证输出序列化
    • 6.验证异常处理
  • 创建自定义 ResultMatcher
  • 匹配 JSON 输出
  • 匹配预期的验证错误
  • 结论

在有关使用 Spring Boot 进行测试的系列的第二部分中,我们将了解 Web 控制器。首先,我们将探索 Web 控制器的实际作用,这样我们就可以构建涵盖其所有职责的测试。

然后,我们将找出如何在测试中涵盖这些职责。只有涵盖了这些职责,我们才能确保我们的控制器在生产环境中按预期运行。

依赖

我们将使用 JUnit Jupiter (JUnit 5) 作为测试框架,使用 Mockito 进行模拟,使用 AssertJ 来创建断言,使用 Lombok 来减少样板代码:

dependencies {
    compile('org.springframework.boot:spring-boot-starter-web')
    compileOnly('org.projectlombok:lombok')
    testCompile('org.springframework.boot:spring-boot-starter-test')
    testCompile('org.junit.jupiter:junit-jupiter:5.4.0')
    testCompile('org.mockito:mockito-junit-jupiter:2.23.0')
}

AssertJ 和 Mockito 跟随 spring-boot-starter-test 依赖自动获得。

Web 控制器的职责

让我们从一个典型的 REST 控制器开始:

@RestController
@RequiredArgsConstructor
class RegisterRestController {
    private final RegisterUseCase registerUseCase;
    @PostMapping("/forums/{forumId}/register")
    UserResource register(@PathVariable("forumId") Long forumId, @Valid @RequestBody UserResource userResource,
            @RequestParam("sendWelcomeMail") boolean sendWelcomeMail) {
        User user = new User(userResource.getName(), userResource.getEmail());
        Long userId = registerUseCase.registerUser(user, sendWelcomeMail);
        return new UserResource(userId, user.getName(), user.getEmail());
    }
}

控制器方法用 @PostMapping 注解来定义它应该侦听的 URL、HTTP 方法和内容类型。

它通过用 @PathVariable、@RequestBody 和 @RequestParam 注解的参数获取输入,这些参数会从传入的 HTTP 请求中自动填充。

参数可以使用 @Valid 进行注解,以指示 Spring 应该对它们 bean 验证。

然后控制器使用这些参数,调用业务逻辑返回一个普通的 Java 对象,默认情况下该对象会自动映射到 JSON 并写入 HTTP 响应体。

这里有很多 spring 魔法。总之,对于每个请求,控制器通常会执行以下步骤:

控制器显然有很多工作要做!

我们应该注意不要添加更多的职责,比如执行业务逻辑。否则,我们的控制器测试将变得臃肿且无法维护。

我们将如何编写有意义的测试,涵盖所有这些职责?

单元测试还是集成测试?

我们写单元测试吗?还是集成测试?到底有什么区别?让我们讨论这两种方法并决定其中一种。

在单元测试中,我们将单独测试控制器。这意味着我们将实例化一个控制器对象,模拟业务逻辑,然后调用控制器的方法并验证响应。

这对我们有用吗?让我们检查一下可以单独的单元测试中涵盖上面确定的 6 个职责中的哪一个:

与 Spring 的集成测试会启动一个包含我们需要的所有 bean 的 Spring 应用程序上下文。这包括负责侦听某些 URL、与 JSON 之间进行序列化和反序列化以及将异常转换为 HTTP 的框架 bean。这些 bean 将评估简单单元测试会忽略的注释。总之,简单的单元测试不会覆盖 HTTP 层。所以,我们需要在我们的测试中引入 Spring 来为我们做 HTTP 魔法。因此,我们正在构建一个集成测试来测试我们的控制器代码和 Spring 为 HTTP 支持提供的组件之间的集成。

那么,我们该怎么做呢?

使用 @WebMvcTest 验证控制器职责

Spring Boot 提供了 @WebMvcTest 注释来启动一个应用程序上下文,该上下文只包含测试 Web 控制器所需的 bean:

@ExtendWith(SpringExtension.class)
@WebMvcTest(controllers = RegisterRestController.class)
class RegisterRestControllerTest {
    @Autowired
    private MockMvc mockMvc;
    @Autowired
    private ObjectMapper objectMapper;
    @MockBean
    private RegisterUseCase registerUseCase;
  @Test
  void whenValidInput_thenReturns200() throws Exception {
    mockMvc.perform(...);
  }
}

@ExtendWith

本教程中的代码示例使用 @ExtendWith 批注告诉 JUnit 5 启用 Spring 支持。从 Spring Boot 2.1 开始,我们不再需要加载 SpringExtension,因为它作为元注释包含在 Spring Boot 测试注解中,例如 @DataJpaTest、@WebMvcTest 和 @SpringBootTest。

我们现在可以 @Autowire 从应用程序上下文中获取我们需要的所有 bean。Spring Boot 自动提供了像 ObjectMapper 这样的 bean 来映射到 JSON 和一个 MockMvc 实例来模拟 HTTP 请求。

我们使用 @MockBean 来模拟业务逻辑,因为我们不想测试控制器和业务逻辑之间的集成,而是控制器和 HTTP 层之间的集成。@MockBean 自动用 Mockito 模拟替换应用程序上下文中相同类型的 bean。

您可以在我关于模拟的文章中阅读有关 @MockBean 注解的更多信息。

使用带或不带 controllers 参数的 @WebMvcTest?

通过在上面的示例中将 controllers 参数设置为 RegisterRestController.class,我们告诉 Spring Boot 将为此测试创建的应用程序上下文限制为给定的控制器 bean 和 Spring Web MVC 所需的一些框架 bean。我们可能需要的所有其他 bean 必须单独包含或使用 @MockBean 模拟。

如果我们不使用 controllers 参数,Spring Boot 将在应用程序上下文中包含所有控制器。因此,我们需要包含或模拟掉任何控制器所依赖的所有 bean。这使得测试设置更加复杂,具有更多的依赖项,但节省了运行时间,因为所有控制器测试都将重用相同的应用程序上下文。

我倾向于将控制器测试限制在最窄的应用程序上下文中,以使测试独立于我在测试中甚至不需要的 bean,即使 Spring Boot 必须为每个单独的测试创建一个新的应用程序上下文。

让我们来回顾一下每个职责,看看我们如何使用 MockMvc 来验证每一个职责,以便构建我们力所能及的最好的集成测试。

1.验证 HTTP 请求匹配

验证控制器是否侦听某个 HTTP 请求非常简单。我们只需调用 MockMvc 的 perform() 方法并提供我们要测试的 URL:

mockMvc.perform(post("/forums/42/register")
    .contentType("application/json"))
    .andExpect(status().isOk());

除了验证控制器对特定 URL 的响应之外,此测试还验证正确的 HTTP 方法(在我们的示例中为 POST)和正确的请求内容类型。我们上面看到的控制器会拒绝任何具有不同 HTTP 方法或内容类型的请求。

请注意,此测试仍然会失败,因为我们的控制器需要一些输入参数。

更多匹配 HTTP 请求的选项可以在 MockHttpServletRequestBuilder 的 Javadoc 中找到。

2.验证输入序列化

为了验证输入是否成功序列化为 Java 对象,我们必须在测试请求中提供它。输入可以是请求正文的 JSON 内容 (@RequestBody)、URL 路径中的变量 (@PathVariable) 或 HTTP 请求参数 (@RequestParam):

@Test
void whenValidInput_thenReturns200() throws Exception {
  UserResource user = new UserResource("Zaphod", "zaphod@galaxy.net");

   mockMvc.perform(post("/forums/{forumId}/register", 42L)
        .contentType("application/json")
        .param("sendWelcomeMail", "true")
        .content(objectMapper.writeValueAsString(user)))
        .andExpect(status().isOk());
}

我们现在提供路径变量 forumId、请求参数 sendWelcomeMail 和控制器期望的请求正文。请求正文是使用 Spring Boot 提供的 ObjectMapper 生成的,将 UserResource 对象序列化为 JSON 字符串。

如果测试结果为绿色,我们现在知道控制器的 register() 方法已将这些参数作为 Java 对象接收,并且它们已从 HTTP 请求中成功解析。

3.验证输入验证

假设 UserResource 使用 @NotNull 注释来拒绝 null 值:

@Value
public class UserResource {
    @NotNull
    private final String name;
    @NotNull
    private final String email;
}

当我们将 @Valid 注解添加到方法参数时,Bean 验证会自动触发,就像我们在控制器中使用 userResource 参数所做的那样。因此,对于快乐路径(即验证成功时),我们在上一节中创建的测试就足够了。

如果我们想测试验证是否按预期失败,我们需要添加一个测试用例,在该用例中我们将无效的 UserResource JSON 对象发送到控制器。然后我们期望控制器返回 HTTP 状态 400(错误请求):

@Test
void whenNullValue_thenReturns400() throws Exception {
  UserResource user = new UserResource(null, "zaphod@galaxy.net");

  mockMvc.perform(post("/forums/{forumId}/register", 42L)
      ...
      .content(objectMapper.writeValueAsString(user)))
      .andExpect(status().isBadRequest());
}

根据验证对应用程序的重要性,我们可能会为每个可能的无效值添加这样的测试用例。但是,这会很快增加很多测试用例,因此您应该与您的团队讨论您希望如何处理项目中的验证测试。

4.验证业务逻辑调用

接下来,我们要验证业务逻辑是否按预期调用。在我们的例子中,业务逻辑由 RegisterUseCase 接口提供,并需要一个 User 对象和一个 boolean 值作为输入:

interface RegisterUseCase {
    Long registerUser(User user, boolean sendWelcomeMail);
}

我们希望控制器将传入的 UserResource 对象转换为 User 并将此对象传递给 registerUser() 方法。

为了验证这一点,我们可以要求 RegisterUseCase 模拟,它已使用 @MockBean 注解注入到应用程序上下文中:

@Test
void whenValidInput_thenMapsToBusinessModel() throws Exception {
  UserResource user = new UserResource("Zaphod", "zaphod@galaxy.net");
  mockMvc.perform(...);
  ArgumentCaptor<User> userCaptor = ArgumentCaptor.forClass(User.class);
  verify(registerUseCase, times(1)).registerUser(userCaptor.capture(), eq(true));
  assertThat(userCaptor.getValue().getName()).isEqualTo("Zaphod");
  assertThat(userCaptor.getValue().getEmail()).isEqualTo("zaphod@galaxy.net");
}

在执行了对控制器的调用之后,我们使用 ArgumentCaptor 来捕获传递给 RegisterUseCase.registerUser() 的 User 对象并断言它包含预期值。

调用 verify 检查 registerUser() 是否被调用过一次。

请注意,如果我们对 User 对象进行大量断言,我们可以 创建自己的自定义 Mockito 断言方法 以获得更好的可读性。

5.验证输出序列化

调用业务逻辑后,我们希望控制器将结果映射到 JSON 字符串并将其包含在 HTTP 响应中。在我们的例子中,我们希望 HTTP 响应正文包含一个有效的 JSON 格式的 UserResource 对象:

@Test
void whenValidInput_thenReturnsUserResource() throws Exception {
  MvcResult mvcResult = mockMvc.perform(...)
      ...
      .andReturn();
  UserResource expectedResponseBody = ...;
  String actualResponseBody = mvcResult.getResponse().getContentAsString();

  assertThat(actualResponseBody).isEqualToIgnoringWhitespace(
              objectMapper.writeValueAsString(expectedResponseBody));
}

要对响应主体进行断言,我们需要使用 andReturn() 方法将 HTTP 交互的结果存储在 MvcResult 类型的变量中。

然后我们可以从响应正文中读取 JSON 字符串,并使用 isEqualToIgnoringWhitespace() 将其与预期的字符串进行比较。我们可以使用 Spring Boot 提供的 ObjectMapper 从 Java 对象构建预期的 JSON 字符串。

请注意,我们可以通过使用自定义的 ResultMatcher 使其更具可读性,稍后对此加以描述。

6.验证异常处理

通常,如果发生异常,控制器应该返回某个 HTTP 状态。400 --- 如果请求有问题,500 --- 如果出现异常,等等。

默认情况下,Spring 会处理大多数这些情况。但是,如果我们有自定义异常处理,我们想测试它。假设我们想要返回一个结构化的 JSON 错误响应,其中包含请求中每个无效字段的字段名称和错误消息。我们会像这样创建一个 @ControllerAdvice:

@ControllerAdvice
class ControllerExceptionHandler {
    @ResponseStatus(HttpStatus.BAD_REQUEST)
    @ExceptionHandler(MethodArgumentNotValidException.class)
    @ResponseBody
    ErrorResult handleMethodArgumentNotValidException(MethodArgumentNotValidException e) {
        ErrorResult errorResult = new ErrorResult();
        for (FieldError fieldError : e.getBindingResult().getFieldErrors()) {
            errorResult.getFieldErrors()
                    .add(new FieldValidationError(fieldError.getField(), fieldError.getDefaultMessage()));
        }
        return errorResult;
    }
    @Getter
    @NoArgsConstructor
    static class ErrorResult {
        private final List<FieldValidationError> fieldErrors = new ArrayList<>();
        ErrorResult(String field, String message) {
            this.fieldErrors.add(new FieldValidationError(field, message));
        }
    }
    @Getter
    @AllArgsConstructor
    static class FieldValidationError {
        private String field;
        private String message;
    }
}

如果 bean 验证失败,Spring 将抛出 MethodArgumentNotValidException。我们通过将 Spring 的 FieldError 对象映射到我们自己的 ErrorResult 数据结构来处理这个异常。在这种情况下,异常处理程序会导致所有控制器返回 HTTP 状态 400,并将 ErrorResult 对象作为 JSON 字符串放入响应正文中。

为了验证这确实发生了,我们扩展了我们之前对失败验证的测试:

@Test
void whenNullValue_thenReturns400AndErrorResult() throws Exception {
  UserResource user = new UserResource(null, "zaphod@galaxy.net");
  MvcResult mvcResult = mockMvc.perform(...)
          .contentType("application/json")
          .param("sendWelcomeMail", "true")
          .content(objectMapper.writeValueAsString(user)))
          .andExpect(status().isBadRequest())
          .andReturn();
  ErrorResult expectedErrorResponse = new ErrorResult("name", "must not be null");
  String actualResponseBody =
      mvcResult.getResponse().getContentAsString();
  String expectedResponseBody =
      objectMapper.writeValueAsString(expectedErrorResponse);
  assertThat(actualResponseBody)
      .isEqualToIgnoringWhitespace(expectedResponseBody);
}

同样,我们从响应正文中读取 JSON 字符串,并将其与预期的 JSON 字符串进行比较。此外,我们检查响应状态是否为 400。

这也可以以可读性更强的方式实现,我们接下来将要学习。

创建自定义 ResultMatcher

某些断言很难写,更重要的是,很难阅读。特别是当我们想要将来自 HTTP 响应的 JSON 字符串与预期值进行比较时,它需要大量代码,正如我们在最后两个示例中看到的那样。

幸运的是,我们可以创建自定义的 ResultMatcher,我们可以在 MockMvc 的流畅 API 中使用它们。让我们看看如何做到这一点。

匹配 JSON 输出

使用以下代码来验证 HTTP 响应正文是否包含某个 Java 对象的 JSON 表示不是很好吗?

@Test
void whenValidInput_thenReturnsUserResource_withFluentApi() throws Exception {
  UserResource user = ...;
  UserResource expected = ...;
  mockMvc.perform(...)
      ...
      .andExpect(responseBody().containsObjectAsJson(expected, UserResource.class));
}

不再需要手动比较 JSON 字符串。它的可读性要好得多。事实上,代码是如此的一目了然,这里我无需解释。

为了能够使用上面的代码,我们创建了一个自定义的 ResultMatcher:

public class ResponseBodyMatchers {
    private ObjectMapper objectMapper = new ObjectMapper();
    public <T> ResultMatcher containsObjectAsJson(Object expectedObject, Class<T> targetClass) {
        return mvcResult -> {
            String json = mvcResult.getResponse().getContentAsString();
            T actualObject = objectMapper.readValue(json, targetClass);
            assertThat(actualObject).isEqualToComparingFieldByField(expectedObject);
        };
    }
    static ResponseBodyMatchers responseBody() {
        return new ResponseBodyMatchers();
    }
}

静态方法 responseBody() 用作我们流畅的 API 的入口点。它返回实际的 ResultMatcher,它从 HTTP 响应正文解析 JSON,并将其与传入的预期对象逐个字段进行比较。

匹配预期的验证错误

我们甚至可以更进一步简化我们的异常处理测试。我们用了 4 行代码来验证 JSON 响应是否包含某个错误消息。我们可以改为一行:

@Test
void whenNullValue_thenReturns400AndErrorResult_withFluentApi() throws Exception {
  UserResource user = new UserResource(null, "zaphod@galaxy.net");
  mockMvc.perform(...)
      ...
      .content(objectMapper.writeValueAsString(user)))
      .andExpect(status().isBadRequest())
      .andExpect(responseBody().containsError("name", "must not be null"));
}

同样,代码是自解释的。

为了启用这个流畅的 API,我们必须从上面添加方法 containsErrorMessageForField() 到我们的 ResponseBodyMatchers 类:

public class ResponseBodyMatchers {
    private ObjectMapper objectMapper = new ObjectMapper();
    public ResultMatcher containsError(String expectedFieldName, String expectedMessage) {
        return mvcResult -> {
            String json = mvcResult.getResponse().getContentAsString();
            ErrorResult errorResult = objectMapper.readValue(json, ErrorResult.class);
            List<FieldValidationError> fieldErrors = errorResult.getFieldErrors().stream()
                    .filter(fieldError -> fieldError.getField().equals(expectedFieldName))
                    .filter(fieldError -> fieldError.getMessage().equals(expectedMessage)).collect(Collectors.toList());
            assertThat(fieldErrors).hasSize(1).withFailMessage(
                    "expecting exactly 1 error message" + "with field name '%s' and message '%s'", expectedFieldName,
                    expectedMessage);
        };
    }
    static ResponseBodyMatchers responseBody() {
        return new ResponseBodyMatchers();
    }
}

所有丑陋的代码都隐藏在这个辅助类中,我们可以在集成测试中愉快地编写干净的断言。

结论

Web 控制器有很多职责。如果我们想用有意义的测试覆盖一个 web 控制器,仅仅检查它是否返回正确的 HTTP 状态是不够的。

通过 @WebMvcTest,Spring Boot 提供了我们构建 Web 控制器测试所需的一切,但为了使测试有意义,我们需要记住涵盖所有职责。否则,我们可能会在运行时遇到丑陋的惊喜。

以上为个人经验,希望能给大家一个参考,也希望大家多多支持我们。

(0)

相关推荐

  • SpringBoot对Controller进行单元测试的实现代码 附乱码解决方案

    Controller代码 package com.keafmd.controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; import java.util.HashMap; import java.util.Map; /** * Keafmd * * @ClassName: Hel

  • spring-mvc/springboot使用MockMvc对controller进行测试

    网上基本都是参考官方的使用方式,使用了import static,个人感觉这种方式特别不好,代码提示性不友好.所以在此进行说明,也方便自己以后使用. 1. 引入spring-test相关jar包,springboot只需引入spring-boot-starter-test即可 <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-tes

  • 使用springboot单元测试对weblistener的加载测试

    目录 springboot单元测试对weblistener的加载测试 原监听器代码 测试类 springboot web做单元测试 springboot单元测试对weblistener的加载测试 使用spring-boot对web项目进行测试时对weblistener进行加载.以proxool连接池的加载为例. 原监听器代码 @WebListener public class ProxoolListener implements ServletContextListener{ @Override

  • SpringBoot Controller Post接口单元测试示例

    概述 在日常的开发中,我们一般会定义一个service层,用于实现业务逻辑,并且针对service层会有与之对应的齐全的覆盖率高的单元测试.而对于controller层,一般不怎么做单元测试,因为主要的核心业务逻辑都在service层里,controller层只是做转发,调用service层接口而已.但是还是建议使用单元测试简单的将controller的方法跑一下,看看转发和数据转换的代码是否能正常工作. 在Spring Boot里对controller层进行单元测试非常简单,只需要几个注解和一

  • SpringBoot 使用@WebMvcTest测试MVC Web Controller

    目录 依赖 Web 控制器的职责 单元测试还是集成测试? 使用 @WebMvcTest 验证控制器职责 @ExtendWith 使用带或不带 controllers 参数的 @WebMvcTest? 1.验证 HTTP 请求匹配 2.验证输入序列化 3.验证输入验证 4.验证业务逻辑调用 5.验证输出序列化 6.验证异常处理 创建自定义 ResultMatcher 匹配 JSON 输出 匹配预期的验证错误 结论 在有关使用 Spring Boot 进行测试的系列的第二部分中,我们将了解 Web

  • SpringBoot 应用程序测试实现方案

    目录 Pre Spring Boot 中的测试解决方案 测试 Spring Boot 应用程序 初始化测试环境 @SpringBootTest @SpringBootTest - webEnvironment @RunWith 注解与 SpringRunner 执行测试用例 使用 @DataJpaTest 注解测试数据访问组件 Service层和Controller的测试 使用 Environment 测试配置信息 使用 Mock 测试 Service 层 测试 Controller 层 小结

  • 基于SpringBoot与Mybatis实现SpringMVC Web项目

    一.热身 一个现实的场景是:当我们开发一个Web工程时,架构师和开发工程师可能更关心项目技术结构上的设计.而几乎所有结构良好的软件(项目)都使用了分层设计.分层设计是将项目按技术职能分为几个内聚的部分,从而将技术或接口的实现细节隐藏起来. 从另一个角度上来看,结构上的分层往往也能促进了技术人员的分工,可以使开发人员更专注于某一层业务与功能的实现,比如前端工程师只关心页面的展示与交互效果(例如专注于HTML,JS等),而后端工程师只关心数据和业务逻辑的处理(专注于Java,Mysql等).两者之间

  • Mockito 结合 Springboot 进行应用测试的方法详解

    Spring Boot可以和大部分流行的测试框架协同工作:通过Spring JUnit创建单元测试:生成测试数据初始化数据库用于测试:Spring Boot可以跟BDD(Behavier Driven Development)工具.Cucumber和Spock协同工作,对应用程序进行测试. 在web应用程序中,我们主要是对Service层做单元测试,以前单元测试都是使用 junit4 ,对Controller层做集成测试或者接口测试,对Controller层的测试一般有两种方法:(1)发送htt

  • SpringBoot中的响应式web应用详解

    简介 在Spring 5中,Spring MVC引入了webFlux的概念,webFlux的底层是基于reactor-netty来的,而reactor-netty又使用了Reactor库. 本文将会介绍在Spring Boot中reactive在WebFlux中的使用. Reactive in Spring 前面我们讲到了,webFlux的基础是Reactor. 于是Spring Boot其实拥有了两套不同的web框架,第一套框架是基于传统的Servlet API和Spring MVC,第二套是

  • 使用springboot开发的第一个web入门程序的实现

    1.新建一个springboot初始化项目 2.输入自己的包名,项目名及jdk版本,再点击Next 3.勾选Spring Web,再点击Next 4.再点击Next,再Finish 默认的项目结构如下图 (1)修改pom.xml文件 完整的pom.xml为: <?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0&qu

  • Springboot配置suffix指定mvc视图的后缀方法

    Springboot配置suffix指定mvc视图后缀 如下所示: spring: #配置MVC视图后缀 mvc: view: suffix: ".html" 配置指定后缀之后 访问welcome.html页面时只需要写"welcome"即可. @Controller public class demoController { @GetMapping("/a") public String demo(){ return "welcome

  • SpringBoot结合mockito测试实战

    题目起的很像那么回事,但是这篇博客本身写的很简单. 我不想写说一堆概念,然后阐释各种概念是什么意思.我喜欢的是直接从例子出发. package com.example.demo.controller; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.example.demo.entity.Person; import com.example.demo.mapper.PersonMappe

  • asp.net MVC 在Controller控制器中实现验证码输出功能

    asp.net mvc项目使用到验证码,为了让以前的WebForm代码能利用上代码经过稍微的改动即可使用代码如下: using System; using System.Collections.Generic; using System.Web; using System.Web.Mvc; using System.Web.UI; using System.Web.UI.WebControls; using System.Drawing; namespace Angel.Web.Controll

  • Springboot整合RabbitMq测试TTL的方法详解

    目录 什么是TTL? 如何设置TTL? 设定整个队列的过期时间 配置类编写 测试 配置 测试 总结 代码下载 什么是TTL? 在RabbitMq中,存在一种高级特性 TTL. TTL即Time To Live的缩写,含义为存活时间或者过期时间.即: 设定消息在队列中存活的时间.当指定时间内,消息依旧未被消费,则由队列自动将其删除. 如何设置TTL? 既然涉及到设定消息的存活时间,在RabbitMq中,存在两种设置方式: 设置整个队列的过期时间. 设置单个消息的过期时间. 设定整个队列的过期时间

随机推荐