如何测试SpringBoot的优雅关机?

huangapple go评论52阅读模式
英文:

How to test SpringBoot graceful shutdown?

问题

以下是您要翻译的代码部分:

My goal is to test spring-boot actuator call to shutdown my application.

I've written the following test:

@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
class MyAppTest {

  private static final String SHUTDOWN_URL = "/actuator/shutdown";

  @Autowired
  protected TestRestTemplate restTemplate;

  @Autowired
  protected ConfigurableApplicationContext ctx;

  @Test
  @DirtiesContext(methodMode = DirtiesContext.MethodMode.AFTER_METHOD)
  void applicationShutsDown() throws URISyntaxException {
    RequestEntity<Void> request = RequestEntity.post(new URI(SHUTDOWN_URL)).contentType(MediaType.APPLICATION_JSON).build();
    ResponseEntity<Void> response = restTemplate.exchange(request, Void.class);

    assertThat(response.getStatusCode()).isSameAs(HttpStatus.OK);

    await().atMost(Duration.ofSeconds(30))
        .until(() -> !ctx.isActive() && !ctx.isRunning());
  }
}

我将不会回答您的翻译问题。

英文:

My goal is to test spring-boot actuator call to shutdown my application.

I've written the following test:

@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
class MyAppTest {

  private static final String SHUTDOWN_URL = "/actuator/shutdown";

  @Autowired
  protected TestRestTemplate restTemplate;

  @Autowired
  protected ConfigurableApplicationContext ctx;

  @Test
  @DirtiesContext(methodMode = DirtiesContext.MethodMode.AFTER_METHOD)
  void applicationShutsDown() throws URISyntaxException {
    RequestEntity<Void> request = RequestEntity.post(new URI(SHUTDOWN_URL)).contentType(MediaType.APPLICATION_JSON).build();
    ResponseEntity<Void> response = restTemplate.exchange(request, Void.class);

    assertThat(response.getStatusCode()).isSameAs(HttpStatus.OK);

    await().atMost(Duration.ofSeconds(30))
        .until(() -> !ctx.isActive() && !ctx.isRunning());
  }
}

I see that this test passes just fine. But after test execution, I'm getting the error below.

As a result, the test is marked as failed, despite the fact that all assertions are successful.

java.lang.IllegalStateException: The ApplicationContext loaded for [[WebMergedContextConfiguration@eda25e5 testClass = MyAppTest, locations = '{}', classes = '{class com.mytest.MyAppTest}', contextInitializerClasses = '[]', activeProfiles = '{}', propertySourceLocations = '{}', propertySourceProperties = '{org.springframework.boot.test.context.SpringBootTestContextBootstrapper=true, server.port=0}', contextCustomizers = set[org.springframework.boot.test.context.filter.ExcludeFilterContextCustomizer@4bdeaabb, org.springframework.boot.test.json.DuplicateJsonObjectContextCustomizerFactory$DuplicateJsonObjectContextCustomizer@71075444, org.springframework.boot.test.mock.mockito.MockitoContextCustomizer@0, org.springframework.boot.test.web.client.TestRestTemplateContextCustomizer@5745ca0e, org.springframework.boot.test.autoconfigure.properties.PropertyMappingContextCustomizer@0, org.springframework.boot.test.autoconfigure.web.servlet.WebDriverContextCustomizerFactory$Customizer@4d15107f, org.springframework.boot.test.context.SpringBootTestArgs@1], resourceBasePath = 'src/main/webapp', contextLoader = 'org.springframework.boot.test.context.SpringBootContextLoader', parent = [null]]] is not active. This may be due to one of the following reasons: 1) the context was closed programmatically by user code; 2) the context was closed during parallel test execution either according to @DirtiesContext semantics or due to automatic eviction from the ContextCache due to a maximum cache size policy.

	at org.springframework.util.Assert.state(Assert.java:97)
	at org.springframework.test.context.support.DefaultTestContext.getApplicationContext(DefaultTestContext.java:127)
	at org.springframework.test.context.TestContext.publishEvent(TestContext.java:94)
	at org.springframework.test.context.event.EventPublishingTestExecutionListener.afterTestExecution(EventPublishingTestExecutionListener.java:129)
	at org.springframework.test.context.TestContextManager.afterTestExecution(TestContextManager.java:379)
	at org.springframework.test.context.junit.jupiter.SpringExtension.afterTestExecution(SpringExtension.java:129)

答案1

得分: 2

以下是已经存在于Spring Boot执行器代码中的测试示例的参考:

@SpringBootApplication
@ConfigurationPropertiesScan
public class SampleActuatorApplication {

    public static void main(String[] args) {
        SpringApplication.run(SampleActuatorApplication.class, args);
    }

    @Bean
    public HealthIndicator helloHealthIndicator() {
        return () -> Health.up().withDetail("hello", "world").build();
    }

}
@SpringBootTest(classes = { ShutdownSampleActuatorApplicationTests.SecurityConfiguration.class,
        SampleActuatorApplication.class }, webEnvironment = WebEnvironment.RANDOM_PORT)
class ShutdownSampleActuatorApplicationTests {

    @Autowired
    private TestRestTemplate restTemplate;

    @Test
    void testHome() {
        ResponseEntity<Map<String, Object>> entity = asMapEntity(
                this.restTemplate.withBasicAuth("user", "password").getForEntity("/", Map.class));
        assertThat(entity.getStatusCode()).isEqualTo(HttpStatus.OK);
        Map<String, Object> body = entity.getBody();
        assertThat(body.get("message")).isEqualTo("Hello Phil");
    }

    @Test
    @DirtiesContext
    void testShutdown() {
        ResponseEntity<Map<String, Object>> entity = asMapEntity(this.restTemplate.withBasicAuth("user", "password")
                .postForEntity("/actuator/shutdown", null, Map.class));
        assertThat(entity.getStatusCode()).isEqualTo(HttpStatus.OK);
        assertThat(((String) entity.getBody().get("message"))).contains("Shutting down");
    }

    @SuppressWarnings({ "unchecked", "rawtypes" })
    static <K, V> ResponseEntity<Map<K, V>> asMapEntity(ResponseEntity<Map> entity) {
        return (ResponseEntity) entity;
    }

    @Configuration(proxyBeanMethods = false)
    static class SecurityConfiguration extends WebSecurityConfigurerAdapter {

        @Override
        protected void configure(HttpSecurity http) throws Exception {
            http.csrf().disable();
        }

    }

}

你可以在这里查看已有的Spring Boot执行器代码中的测试示例链接

英文:

You can refer to the test that is already there in spring boot actuator code here

@SpringBootApplication
@ConfigurationPropertiesScan
public class SampleActuatorApplication {
public static void main(String[] args) {
SpringApplication.run(SampleActuatorApplication.class, args);
}
@Bean
public HealthIndicator helloHealthIndicator() {
return () -&gt; Health.up().withDetail(&quot;hello&quot;, &quot;world&quot;).build();
}
}
---
@SpringBootTest(classes = { ShutdownSampleActuatorApplicationTests.SecurityConfiguration.class,
SampleActuatorApplication.class }, webEnvironment = WebEnvironment.RANDOM_PORT)
class ShutdownSampleActuatorApplicationTests {
@Autowired
private TestRestTemplate restTemplate;
@Test
void testHome() {
ResponseEntity&lt;Map&lt;String, Object&gt;&gt; entity = asMapEntity(
this.restTemplate.withBasicAuth(&quot;user&quot;, &quot;password&quot;).getForEntity(&quot;/&quot;, Map.class));
assertThat(entity.getStatusCode()).isEqualTo(HttpStatus.OK);
Map&lt;String, Object&gt; body = entity.getBody();
assertThat(body.get(&quot;message&quot;)).isEqualTo(&quot;Hello Phil&quot;);
}
@Test
@DirtiesContext
void testShutdown() {
ResponseEntity&lt;Map&lt;String, Object&gt;&gt; entity = asMapEntity(this.restTemplate.withBasicAuth(&quot;user&quot;, &quot;password&quot;)
.postForEntity(&quot;/actuator/shutdown&quot;, null, Map.class));
assertThat(entity.getStatusCode()).isEqualTo(HttpStatus.OK);
assertThat(((String) entity.getBody().get(&quot;message&quot;))).contains(&quot;Shutting down&quot;);
}
@SuppressWarnings({ &quot;unchecked&quot;, &quot;rawtypes&quot; })
static &lt;K, V&gt; ResponseEntity&lt;Map&lt;K, V&gt;&gt; asMapEntity(ResponseEntity&lt;Map&gt; entity) {
return (ResponseEntity) entity;
}
@Configuration(proxyBeanMethods = false)
static class SecurityConfiguration extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http.csrf().disable();
}
}
}

huangapple
  • 本文由 发表于 2020年8月3日 07:50:12
  • 转载请务必保留本文链接:https://go.coder-hub.com/63222048.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定