makozaki
makozaki

Reputation: 4366

No qualifying bean of type 'org.springframework.boot.actuate.health.HealthEndpoint' in controller test

I wrote a controller which combines actuator info.

@RestController
@Slf4j
public class AppStatusRestController {
    private final HealthEndpoint healthEndpoint;
    private final InfoEndpoint infoEndpoint;

    public AppStatusRestController(HealthEndpoint healthEndpoint, InfoEndpoint infoEndpoint) {
        this.healthEndpoint = healthEndpoint;
        this.infoEndpoint = infoEndpoint;
    }

    @GetMapping("/status")
    public Status status() {
        Map<String, Object> info = infoEndpoint.info();
        return Status.builder()
                .status(healthEndpoint.health().getStatus().getCode())
                .appName("My application")
                .version(((Map<String, Object>) info.get("build")).get("version").toString())
                .buildDateTime(((Map<String, Object>) info.get("build")).get("timestamp").toString())
                .build();
    }
}

In my test I get an error No qualifying bean of type 'org.springframework.boot.actuate.health.HealthEndpoint'.

@SpringBootTest(classes = AppStatusRestController.class)
@TestPropertySource(properties = "management.endpoints.web.exposure.include=*")
class AppStatusRestControllerTest {

    @Test
    void status() {
    }
}

How can I actiavate default spring actuator beans in controller test(@SpringBootTest/@WebMvcTest)?

Upvotes: 3

Views: 6426

Answers (3)

red
red

Reputation: 916

You can use @SpringBootTest() with no classes and it will work too. In this case, Spring will load the full context for executing the tests.

@SpringBootTest()
@AutoConfigureMockMvc
@TestPropertySource(properties = { "management.endpoints.web.exposure.include=health,info" })
class AppStatusRestControllerTest {

    @Autowired
    private MockMvc mockMvc;

    @Test
    void version() throws Exception {
        MvcResult mvcResult = this.mockMvc.perform(get("/status")).andReturn();
        String contentAsString = mvcResult.getResponse().getContentAsString();
        ObjectMapper objectMapper = new ObjectMapper();
        Status result = objectMapper.readValue(contentAsString, Status.class);
        assertEquals(result.getStatus(), "UP");
    }
}

Upvotes: 1

makozaki
makozaki

Reputation: 4366

I fixed the problem by creating TestApplication.java which includes only one controller of my application. Then I'm testing by loading test app into context @SpringBootTest(classes = TestApplication.class).

@SpringBootApplication
@Import(AppStatusRestController.class)
public class TestApplication {
    public static void main(String[] args) {
        SpringApplication.run(TestApplication.class, args);
    }
}
@SpringBootTest(classes = TestApplication.class)
@AutoConfigureMockMvc
@TestPropertySource(properties = { "management.endpoints.web.exposure.include=health,info" })
class AppStatusRestControllerTest {

    @Autowired
    private MockMvc mockMvc;

    @Test
    void version() throws Exception {
        MvcResult mvcResult = this.mockMvc.perform(get("/status")).andReturn();
        String contentAsString = mvcResult.getResponse().getContentAsString();
        ObjectMapper objectMapper = new ObjectMapper();
        Status result = objectMapper.readValue(contentAsString, Status.class);
        assertEquals(result.getStatus(), "UP");
    }
}

Upvotes: 0

Sergey Tsypanov
Sergey Tsypanov

Reputation: 4370

I guess I'm narrowing down the context is the answer to your question: Spring includes only the controller into its context skipping everything else. Try to include HealthEndpointAutoConfiguration too.

Upvotes: 2

Related Questions