【问题标题】:Unit testing of Spring Boot Actuator endpoints not working when specifying a port指定端口时,Spring Boot Actuator 端点的单元测试不起作用
【发布时间】:2016-11-25 02:48:41
【问题描述】:

最近我更改了 Spring Boot 属性以定义管理端口。 这样做,我的单元测试开始失败:​​(

我编写了一个单元测试来测试 /metrics 端点,如下所示:

@RunWith (SpringRunner.class)
@DirtiesContext
@SpringBootTest
public class MetricsTest {

    @Autowired
    private WebApplicationContext context;

    private MockMvc mvc;

    /**
     * Called before each test.
     */
    @Before
    public void setUp() {
        this.context.getBean(MetricsEndpoint.class).setEnabled(true);
        this.mvc = MockMvcBuilders.webAppContextSetup(this.context).build();
    }

    /**
     * Test for home page.
     *
     * @throws Exception On failure.
     */
    @Test
    public void home()
            throws Exception {
        this.mvc.perform(MockMvcRequestBuilders.get("/metrics"))
                .andExpect(MockMvcResultMatchers.status().isOk());
    }
}        

以前这是通过的。添加后:

management.port=9001

测试开始失败:

home Failed: java.lang.AssertionError: Status expected: <200> but was: <404>

我尝试更改 @SpringBootTest 注释:

@SpringBootTest (properties = {"management.port=<server.port>"})

server.port 使用的号码在哪里。这似乎没有任何区别。

然后将属性文件中的 management.port 值更改为与 server.port 相同。结果一样。

让测试工作的唯一方法是从属性文件中删除 management.port。

有什么建议/想法吗?

谢谢

【问题讨论】:

  • 因此为成功和失败案例添加了一些跟踪日志记录。在成功的情况下,我看到以下内容:TRACE [Test worker] --- org.springframework.test.web.servlet.TestDispatcherServlet: Testing handler map [org.springframework.boot.actuate.endpoint.mvc.EndpointHandlerMapping@2281521a] in DispatcherServlet with name 这在失败的情况下丢失了。所以我只能假设我使用了错误的值 MockMvcBuilders.webAppContextSetup(this.context)

标签: java spring-boot junit spring-boot-actuator


【解决方案1】:

尝试使用

@SpringBootTest(properties = {"management.port="})

@SpringBootTest 注释中定义的属性比应用程序属性中的属性具有higher precedence"management.port=" 将“取消设置”management.port 属性。
这样您就不必担心在测试中配置端口。

【讨论】:

  • 您能否为您的答案添加一些解释?
【解决方案2】:

您是否尝试将以下注释添加到您的测试类?

@TestPropertySource(properties = {"management.port=0"})

Check the following link for reference

【讨论】:

    【解决方案3】:

    遇到同样的问题,您只需将 management.port 添加到您的 application-test.properties 中即可(将其设置为空值)

    management.port=
    

    通过注释类来确保在 JUnit 中使用测试配置文件

    @ActiveProfiles("test")
    

    【讨论】:

      【解决方案4】:

      对于 Spring 启动测试,我们需要指定它需要连接的端口。

      默认情况下,它连接到server.port,如果执行器不同。

      这可以通过

      @SpringBootTest(properties = "server.port=8090")
      

      application.properties我们指定管理端口如下

      ...
      management.server.port=8090
      ...
      

      【讨论】:

        【解决方案5】:

        是不是属性名有错误? 不应该 @TestPropertySource(properties = {"management.server.port=..."}) 而不是 @TestPropertySource(properties = {"management.port=.."})

        【讨论】:

          【解决方案6】:

          对于 Spring Boot 2.x,可以简化集成测试配置。

          例如简单的自定义heartbeat端点

          @Component
          @Endpoint(id = "heartbeat")
          public class HeartbeatEndpoint {
          
              @ReadOperation
              public String heartbeat() {
                  return "";
              }
          }
          

          此端点的集成测试在哪里

          @SpringBootTest(
                  classes = HeartbeatEndpointTest.Config.class,
                  properties = {
                          "management.endpoint.heartbeat.enabled=true",
                          "management.endpoints.web.exposure.include=heartbeat"
                  })
          @AutoConfigureMockMvc
          @EnableAutoConfiguration
          class HeartbeatEndpointTest {
          
              private static final String ENDPOINT_PATH = "/actuator/heartbeat";
          
              @Autowired
              private MockMvc mockMvc;
          
              @Test
              void testHeartbeat() throws Exception {
                  mockMvc
                          .perform(get(ENDPOINT_PATH))
                          .andExpect(status().isOk())
                          .andExpect(content().string(""));
              }
          
              @Configuration
              @Import(ProcessorTestConfig.class)
              static class Config {
          
                  @Bean
                  public HeartbeatEndpoint heartbeatEndpoint() {
                      return new HeartbeatEndpoint();
                  }
          
              }
          
          }    
          

          【讨论】:

          • 感谢分享。如何添加负面用例?
          【解决方案7】:

          我遇到了同样的问题并尝试了几件事,但这就是我能够在不更改 application.yaml 的情况下解决我的问题的方法

          执行器端点示例

          @Component
          @RestControllerEndpoint(id = "endpoint")
          public class SampleEndpoint
          {
              @GetMapping
              public String sampleEndpoint(){
                return ""
              }
          }
          

          单元测试用例

          @RunWith(SpringRunner.class)
          @SpringBootTest(
              classes = {SampleEndpointTest.Config.class},
              properties = {"management.server.port="}
          )
          @AutoConfigureMockMvc
          public class SampleEndpointTest
          {
              @Autowired
              private MockMvc mockMvc;
          
              @SpringBootApplication(scanBasePackageClasses = {SampleEndpoint.class})
              public static class Config
              {
              }
          
              @Test
              public void testSampleEndpoint() throws Exception
              {
          
                  mockMvc.perform(
                      MockMvcRequestBuilders.get("/actuator/enpoint").accept(APPLICATION_JSON)
                  ).andExpect(status().isOk());
              }
          

          【讨论】:

            【解决方案8】:

            指南指出这可以通过@AutoConfigureMetrics 来实现。 我也跟着搬家了。

            无论您的类路径如何,在使用 @SpringBootTest 时,计量注册表(内存中支持的除外)都不会自动配置。 如果您需要在集成测试中将指标导出到不同的后端,请使用 @AutoConfigureMetrics 对其进行注释。

            https://docs.spring.io/spring-boot/docs/current/reference/html/features.html#features.testing.spring-boot-applications.metrics

            【讨论】:

              【解决方案9】:

              现在必须手动启用 info 端点,确保 SpringBootTest 标记在属性中包含此内容,如下所示:

              @SpringBootTest(
                      properties = {
                              "management.info.env.enabled=true" ,
                              "management.endpoints.web.exposure.include=info, health"
                      })
              

              【讨论】:

                猜你喜欢
                • 1970-01-01
                • 1970-01-01
                • 2021-04-24
                • 2019-03-13
                • 1970-01-01
                • 1970-01-01
                • 2016-06-01
                • 1970-01-01
                • 1970-01-01
                相关资源
                最近更新 更多