获取"必须至少存在一个JPA元模型"与@WebMvcTest

时间:2016-12-20 19:49:26

标签: java spring-mvc spring-boot spring-data-jpa integration-testing

我是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: 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!

与发布此错误的大多数人不同,我不想使用JPA 。我是否尝试错误地使用@WebMvcTest?我怎样才能找到邀请JPA参加这个派对的春天魔术?

5 个答案:

答案 0 :(得分:14)

从您的private void Txt_Loaded(object sender, RoutedEventArgs e) { var myText = (sender as TextBlock).Text; } 课程中删除所有@EnableJpaRepositories@EntityScan,然后执行此操作:

SpringBootApplication

并将其放在单独的配置类中:

package com.tdk;

@SpringBootApplication
@Import({ApplicationConfig.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 {

}

答案 1 :(得分:5)

或者,您可以在测试用例中定义自定义配置类,仅包括控制器(以及它的依赖项),以强制Spring使用上下文。
请注意,如果MockMvc注释了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 {} 和其他优点。

max

答案 2 :(得分:4)

我遇到了同样的问题。 @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
    }
}

希望这有帮助!

答案 3 :(得分:1)

如果任何人使用Spring Boot并不想删除@EntityScan@EnableJpaRepositories,则可以从测试类中删除@WebMvcTest批注,并添加以下内容:

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

    //...
}

,您将能够自动连接MockMvc并使用它。

答案 4 :(得分:0)

在课程@MockBean(JpaMetamodelMappingContext.class)的上方添加DemoControllerIntegrationTests

@RunWith(SpringRunner.class)
@WebMvcTest(DemoController.class)
@MockBean(JpaMetamodelMappingContext.class)
public class DemoControllerIntegrationTests {
    ...
}

由于您没有在测试中使用数据库,因此Spring抛出此异常。通过模拟JpaMetamodelMappingContext类,您将绕过所需的元模型。