11

I have a Spring App that uses JPA repositories (CrudRepository interfaces). When I try to test my controller using the new Spring test syntax @WebMvcTest(MyController.class), it fails coz it tries to instantiate one of my service class that uses JPA Repository, does anyone has any clues on how to fix that? The app works when I run it.

Here is the error:

***************************
APPLICATION FAILED TO START
***************************

Description:

Parameter 0 of constructor in com.myapp.service.UserServiceImpl required a bean of type 'com.myapp.repository.UserRepository' that could not be found.

Action:

Consider defining a bean of type 'com.myapp.repository.UserRepository' in your configuration.
Jens Schauder
  • 77,657
  • 34
  • 181
  • 348
dickyj
  • 1,830
  • 1
  • 24
  • 41

3 Answers3

15

According to the doc

Using this annotation will disable full auto-configuration and instead apply only configuration relevant to MVC tests (i.e. @Controller, @ControllerAdvice, @JsonComponent Filter, WebMvcConfigurer and HandlerMethodArgumentResolver beans but not @Component, @Service or @Repository beans).

This annotion only apply on the Spring MVC components.

If you are looking to load your full application configuration and use MockMVC, you should consider @SpringBootTest combined with @AutoConfigureMockMvc rather than this annotation.

Liping Huang
  • 4,378
  • 4
  • 29
  • 46
  • Yes, you are right, I ended up using the method you mentioned, and it works. – dickyj Oct 10 '16 at 05:34
  • A link to the docs. https://docs.spring.io/spring-boot/docs/current/api/org/springframework/boot/test/autoconfigure/web/servlet/WebMvcTest.html – Peter Chaula May 03 '20 at 18:11
2

I was able to unit test a Rest Controller by implementing junit 5 and using @SpringJUnitConfig along with @WebMvcTest. I am using Spring Boot 2.4.5 and this is my example:

@SpringJUnitConfig
@WebMvcTest(controllers = OrderController.class)
class OrderControllerTest {

    @Autowired
    private MockMvc mockMvc;

    // This is a Mock bean of a Spring Feign client that calls an external Rest Api
    @MockBean
    private LoginServiceClient loginServiceClient;

    // This is a Mock for a class which has several Spring Jpa repositories classes as dependencies
    @MockBean
    private OrderService orderService;

    @DisplayName("should create an order")
    @Test
    void createOrder() throws Exception {

        OrderEntity createdOrder = new OrderEntity("123")

        when(orderService.createOrder(any(Order.class))).thenReturn(createdOrder);

        mockMvc.perform(post("/api/v1/orders").contentType(MediaType.APPLICATION_JSON).content("{orderId:123}"))
            .andExpect(status().isCreated())
            .andExpect(content().contentType(MediaType.APPLICATION_JSON_UTF8))TODO: here it will go the correlationId
            .andExpect(jsonPath("$.orderId").value("123"));
    }
}

Please only use @SpringBootTest when you are implementing integration tests.

jcflorezr
  • 326
  • 4
  • 13
1

I faced this same problem. Using @SpringBootTest and @AutoConfigureMockMvc worked perfectly for me.

Sasikumar Murugesan
  • 4,412
  • 10
  • 51
  • 74
Edor Linus
  • 826
  • 8
  • 9