Spring Annotation @WebMvcTest does not work in an app that has Jpa repositories
Asked Answered
A

4

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.
Adrenalin answered 10/10, 2016 at 2:40 Comment(1)
Please share your pom.xml and complete stack trace to deep dive.Equanimity
H
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.

Hokeypokey answered 10/10, 2016 at 5:25 Comment(2)
Yes, you are right, I ended up using the method you mentioned, and it works.Adrenalin
A link to the docs. docs.spring.io/spring-boot/docs/current/api/org/springframework/…Komsomol
E
2

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

Ethben answered 20/7, 2020 at 10:35 Comment(0)
R
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.

Roselynroseman answered 4/5, 2021 at 4:3 Comment(0)
S
0

You should manual config Data Jpa(https://docs.spring.io/spring-data/jpa/docs/current/reference/html/#jpa.java-config) then use @Import annotation in test file instead of use @SpringBootTest to load all bean in system that will very expense(time and resource) when run test

Sonia answered 19/9, 2023 at 2:9 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.