I am trying to run following test case and expecting only Web Layer @WebMvcTest
will be tested and rest of the things will be mocked automatically.
Error
Caused by: java.lang.IllegalArgumentException: JPA metamodel must not be empty
at org.springframework.util.Assert.notEmpty(Assert.java:479)
at org.springframework.data.jpa.mapping.JpaMetamodelMappingContext.<init>(JpaMetamodelMappingContext.java:58)
at org.springframework.data.jpa.repository.config.JpaMetamodelMappingContextFactoryBean.createInstance(JpaMetamodelMappingContextFactoryBean.java:68)
at org.springframework.data.jpa.repository.config.JpaMetamodelMappingContextFactoryBean.createInstance(JpaMetamodelMappingContextFactoryBean.java:44)
at org.springframework.beans.factory.config.AbstractFactoryBean.afterPropertiesSet(AbstractFactoryBean.java:142)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1808)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1758)
... 105 more
Test Code
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
import org.springframework.test.web.servlet.MockMvc;
import static org.hamcrest.Matchers.is;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
@WebMvcTest(WelcomeController.class) // Loads only the web layer
public class TestWelcomeController {
@Autowired
private MockMvc mockMvc; // Provides MockMvc for performing requests
@Test
public void testGetBooking() throws Exception {
mockMvc.perform(get("/"))
.andDo(print())
.andExpect(status().isOk())
.andExpect(jsonPath("status", is("OK")))
;
}
}
Please note WelcomeController
does not depend on any other class and I was hoping it will work perfectly fine without loading anything else.
To fix this I have to replace
@WebMvcTest(WelcomeController.class)
with
@AutoConfigureMockMvc
@SpringBootTest
Everything works like a charm. What is happening if I have to mock everything in order to run this it means @WebMvcTest
has zero value in case if any entity is being used
Questions:
- Does
@WebMvcTest
have any usage? if JPAs etc are used but directly not involved in Controller under test @SprnigBootTest
creates application context but mock Web Layer as the defaultwebEnvironemnt = MOCK
, and hence we use MockMvc which almost does everything simulating HTTP calls by Mocking and does not make any Network calls .@SpringBootTest(webEnvironment = RANDOM_PORT)
loads embedded web-server, Beladung and most other tutorials blogs still use MockMvc with this configuration, does MockMvc change its behaviour if webEnvironment is used? or it will still work the same?- What is the difference between web layer mocking in case of
@WebMvcTest
and@SpringBootTest(webEnvironment = RANDOM_PORT)
I know SpringBootTest loads the application context as well, but is there any change on web layer mocking?