使用@WebMvcTest获取“必须至少存在一个JPA元模型”
我是Spring的新手,试图为@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()); } }
但我得到了
java.lang.IllegalStateException:无法加载ApplicationContext 引起:org.springframework.beans.factory.BeanCreationException:创建名为'jpaMappingContext'的bean时出错:init方法的调用失败; 嵌套exception是java.lang.IllegalArgumentException:必须至少存在一个JPA元模型! 引起:java.lang.IllegalArgumentException:必须至少存在一个JPA元模型!
与发布此错误的大多数人不同, 我不想为此使用JPA 。 我试图错误地使用@WebMvcTest
吗? 我怎样才能找到邀请JPA加入这个派对的Spring魔法?
从SpringBootApplication类中删除任何@EnableJpaRepositories
或@EntityScan
,而不是这样做:
package com.tdk; @SpringBootApplication @Import({SecurityConfig.class }) public class TdkApplication { public static void main(String[] args) { SpringApplication.run(TdkApplication.class, args); } }
并将它放在一个单独的配置类中:
package com.tdk.config; @Configuration @EnableJpaRepositories(basePackages = "com.tdk.repositories") @EntityScan(basePackages = "com.tdk.domain") @EnableTransactionManagement public class ApplicationConfig { }
在这里测试:
@RunWith(SpringRunner.class) @WebAppConfiguration @WebMvcTest public class MockMvcTests { }
我有同样的问题。 @WebMvcTest查找使用@SpringBootApplication注释的类(如果找不到,则在应用程序结构的同一目录或更高版本中)。 你可以阅读它的工作原理@ https://docs.spring.io/spring-boot/docs/current/reference/htmlsingle/#boot-features-testing-spring-boot-applications-testing-autoconfigured-mvc-tests 。
如果使用@SpringBootApplication注释的类也具有@EntityScan / @ EnableJpaRepositories,则会发生此错误。 因为您在@SpringBootApplication中有这些注释,并且您正在模拟该服务(因此实际上不使用任何JPA)。 我找到了一个可能不是最漂亮的解决方法,但对我有用。
将此类放在测试目录(根目录)中。 @WebMvcTest将在您的实际Application类之前找到此类。 在这个类中,您不必添加@EnableJpaRepositories / @ EntityScan。
@SpringBootApplication(scanBasePackageClasses = { xxx.service.PackageMarker.class, xxx.web.PackageMarker.class }) public class Application { }
你的测试看起来会一样。
@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 } }
希望这可以帮助!
或者,您可以在测试用例中定义自定义配置类,仅包括控制器(加上它的依赖项),以强制Spring使用此上下文。
请注意,如果是WebMvcTest
注释,您仍然可以访问MockMvc
以及测试用例中的其他优点。
@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 {}