Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

SpringBoot @WebMvcTest, autowiring RestTemplateBuilder

I've got a problem while testing a Spring Controller. I'm using the annotation @WebMvcTest in my test class. When I run the test, I get this error: No qualifying bean of type 'org.springframework.boot.web.client.RestTemplateBuilder' available

I'm using RestTemplate for other classes in my project so I've defined a bean in my main class:

@Bean
public RestTemplate restTemplate(RestTemplateBuilder builder) {
    return builder.build();
}

To make it work, I have to define my restTemplate bean this way:

@Bean
public RestTemplate restTemplate() {
    return new RestTemplate();
}

Is it a problem with the annotation @WebMvcTest or did I miss something?

Thanks

like image 982
Alexandre Avatar asked Jan 16 '17 09:01

Alexandre


3 Answers

Yes, this does feel like a bug.
However you can solve it easily by adding @AutoConfigureWebClient to your test class along with the existing @WebMvcTest

like image 101
Patrick Herrera Avatar answered Nov 03 '22 03:11

Patrick Herrera


when you add any argument to the @Bean definition it means that you are looking for a bean of type T mentioned to be injected . Change this :

@Bean
public RestTemplate restTemplate(RestTemplateBuilder builder) {
    return builder.build();
}

to

 @Bean
    public RestTemplate restTemplate() {

       RestTemplateBuilder builder=new RestTemplateBuilder(//pass customizers);

        return builder.build();
    }
like image 4
Barath Avatar answered Nov 03 '22 01:11

Barath


When I'm writing my Controller tests, I generally prefer to use mocks for all the collaborators. This makes it super easy to verify your beans are getting called with the values that you expect, without actually performing the call.

With WebMvcTest this is super easy to pull off, below is an example given your RestTemplate Bean.

@RunWith(SpringRunner.class)
@WebMvcTest(SomeController.class)
public class SomeControllerTest {

   @MockBean
   private RestTemplate restTemplate;

   @Test
   public void get_WithData() {
      mockMvc.perform(get("/something")).andExpect(status().isOk());
      verify(restTemplate, times(1)).getForObject("http://localhost:8080/something", SomeClass.class);
   }
}
like image 4
lane.maxwell Avatar answered Nov 03 '22 02:11

lane.maxwell