test starter example datajpatest java spring-mvc spring-boot spring-data-jpa integration-testing

java - starter - Obtener "Al menos un metamodelo JPA debe estar presente" con @WebMvcTest



spring test (4)

Soy bastante nuevo en Spring e intento hacer algunas pruebas de integración básicas para un @Controller .

@RunWith(SpringRunner.class) @WebMvcTest(DemoController.class) public class DemoControllerIntegrationTests { @Autowired private MockMvc mvc; @MockBean private DemoService demoService; @Test public void index_shouldBeSuccessful() throws Exception { mvc.perform(get("/home").accept(MediaType.TEXT_HTML)).andExpect(status().isOk()); } }

pero me estoy poniendo

java.lang.IllegalStateException: Failed to load ApplicationContext Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name ''jpaMappingContext'': Invocation of init method failed; nested exception is java.lang.IllegalArgumentException: At least one JPA metamodel must be present! Caused by: java.lang.IllegalArgumentException: At least one JPA metamodel must be present!

A diferencia de la mayoría de las personas que publican este error, no quiero usar JPA para esto. ¿Estoy tratando de usar @WebMvcTest incorrectamente? ¿Cómo puedo rastrear la magia de primavera que invita a JPA a esta fiesta?


Alternativamente, puede definir una clase de configuración personalizada dentro de su caso de prueba, incluyendo solo el controlador (más sus dependencias), para forzar a Spring a usar este contexto.
Tenga en cuenta que aún tendrá acceso a MockMvc y otras bondades en su caso de prueba, si está anotado en WebMvcTest .

@RunWith(SpringRunner.class) @WebMvcTest(DemoController.class) public class DemoControllerIntegrationTests { @Autowired private MockMvc mvc; @MockBean private DemoService demoService; @Test public void index_shouldBeSuccessful() throws Exception { mvc.perform(get("/home").accept(MediaType.TEXT_HTML)).andExpect(status().isOk()); } @Configuration @ComponentScan(basePackageClasses = { DemoController.class }) public static class TestConf {}


Elimine cualquier @EnableJpaRepositories o @EntityScan de su clase SpringBootApplication lugar de hacer esto:

package com.tdk; @SpringBootApplication @Import({ApplicationConfig.class }) public class TdkApplication { public static void main(String[] args) { SpringApplication.run(TdkApplication.class, args); } }

Y ponerlo en una clase de configuración separada:

package com.tdk.config; @Configuration @EnableJpaRepositories(basePackages = "com.tdk.repositories") @EntityScan(basePackages = "com.tdk.domain") @EnableTransactionManagement public class ApplicationConfig { }

Y aquí las pruebas:

@RunWith(SpringRunner.class) @WebAppConfiguration @WebMvcTest public class MockMvcTests { }


Si alguien utiliza Spring Boot y no desea eliminar @EntityScan y @EnableJpaRepositories , puede eliminar la anotación @WebMvcTest de su clase de prueba y agregar lo siguiente:

@RunWith(SpringRunner.class) @SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) @AutoConfigureMockMvc public class DemoControllerIntegrationTests { @Autowired private MockMvc mvc; //... }

y podrás autowire MockMvc y usarlo.


Yo tuve el mismo problema. @WebMvcTest busca una clase anotada con @SpringBootApplication (en el mismo directorio o superior en la estructura de la aplicación si no encuentra una). Puedes leer cómo funciona esto en https://docs.spring.io/spring-boot/docs/current/reference/htmlsingle/#boot-features-testing-spring-boot-applications-testing-autoconfigured-mvc-tests .

Si su clase anotada con @SpringBootApplication también tiene @EntityScan / @ EnableJpaRepositories, se produce este error. Porque tienes estas anotaciones con @SpringBootApplication y te estás burlando del servicio (por lo que en realidad no estás usando ninguna JPA). He encontrado una solución que puede no ser la más bonita, pero funciona para mí.

Coloque esta clase en su directorio de prueba (la raíz). @WebMvcTest encontrará esta clase antes de su clase de aplicación real. En esta clase no tiene que agregar @ EnableJpaRepositories / @ EntityScan.

@SpringBootApplication(scanBasePackageClasses = { xxx.service.PackageMarker.class, xxx.web.PackageMarker.class }) public class Application { }

Y tu prueba se verá igual.

@RunWith(SpringRunner.class) @WebMvcTest @WithMockUser public class ControllerIT { @Autowired private MockMvc mockMvc; @MockBean private Service service; @Test public void testName() throws Exception { // when(service.xxx(any(xxx.class))).thenReturn(xxx); // mockMvc.perform(post("/api/xxx")... // some assertions } }

¡Espero que esto ayude!