Reputation: 1870
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.
Upvotes: 11
Views: 10460
Reputation: 74
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
Upvotes: 0
Reputation: 336
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.
Upvotes: 3
Reputation: 1146
I faced this same problem. Using @SpringBootTest
and @AutoConfigureMockMvc
worked perfectly for me.
Upvotes: 2
Reputation: 4476
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.
Upvotes: 15