Spring Boot 1.4.2,hibernate 5.2.3,Junit测试存储库,@ DataJpaTest问题,版本冲突?

时间:2016-12-20 18:04:51

标签: java hibernate spring-boot junit spring-data-jpa

我是Spring Boot的新手,我正在尝试测试存储库。 这就是我试过的:

@RunWith(SpringRunner.class)
@DataJpaTest
public class MyRepositoryTest {

    @Autowired
    private TestEntityManager entityManager;

    @Autowired
    private MyRepository repository;

但是我得到以下例外:

  

java.lang.IllegalStateException:无法加载ApplicationContext       at org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate.loadContext(DefaultCacheAwareContextLoaderDelegate.java:124)   ...   引起:org.springframework.beans.factory.BeanCreationException:在org.springframework.web.servlet.config.annotation.DelegatingWebMvcConfiguration中定义名称为'defaultServletHandlerMapping'的bean创建错误:通过工厂方法进行Bean实例化失败;嵌套异常是org.springframework.beans.BeanInstantiationException:无法实例化[org.springframework.web.servlet.HandlerMapping]:工厂方法'defaultServletHandlerMapping'抛出异常;嵌套异常是java.lang.IllegalArgumentException:需要ServletContext来配置默认的servlet处理       在org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:599)   ...   引起:org.springframework.beans.BeanInstantiationException:无法实例化[org.springframework.web.servlet.HandlerMapping]:工厂方法'defaultServletHandlerMapping'抛出异常;嵌套异常是java.lang.IllegalArgumentException:需要ServletContext来配置默认的servlet处理       在org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:189)   ...   引起:java.lang.IllegalArgumentException:需要ServletContext来配置默认的servlet处理       在org.springframework.util.Assert.notNull(Assert.java:115)       在org.springframework.web.servlet.config.annotation.DefaultServletHandlerConfigurer。(DefaultServletHandlerConfigurer.java:53)   ...

我运行了一些没有问题的JUnit测试,只使用以下注释:

@ActiveProfiles("junit")
@RunWith(SpringRunner.class)
@SpringBootTest(webEnvironment = WebEnvironment.DEFINED_PORT)
public class MyControllerTest {

对于存储库Junit测试,我需要使用TestEntityManager来确保存储库完成它的工作,似乎使用@DataJpaTest就是这样做的方法。但如上所述,我得到了例外。

我尝试了其他一些注释组合,但异常没有消失。

如果我的maven依赖是错误的,那么它们就是:

<properties>
    <spring.boot.version>1.4.2.RELEASE</spring.boot.version>
    ....
</properties
<dependencyManagement>
    <dependencies>
        <dependency>
            <!-- Import dependency management from Spring Boot -->
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-dependencies</artifactId>
            <version>${spring.boot.version}</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
    </dependencies>
</dependencyManagement>

<dependencies>

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-tomcat</artifactId>
        <scope>provided</scope>
    </dependency>

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-test</artifactId>
        <scope>test</scope>
    </dependency>

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-security</artifactId>
        <scope>runtime</scope>
    </dependency>

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-data-jpa</artifactId>
        <version>${spring.boot.version}</version>
        <exclusions>
            <exclusion>
                <groupId>org.hibernate</groupId>
                <artifactId>hibernate-entitymanager</artifactId>
            </exclusion>
        </exclusions>
    </dependency>

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-jdbc</artifactId>
        <version>${spring.boot.version}</version>
    </dependency>

  ....
    <dependency>
        <groupId>org.hibernate</groupId>
        <artifactId>hibernate-core</artifactId>
    </dependency>

正如您所看到的,由于版本冲突,我不得不排除hibernate-entitymanager。这是它不起作用的原因吗?

这是否意味着我必须切换回旧版本的hibernate来使其工作?

我很确定JUnit存储库测试需要我的application-junit.properties文件,该文件使用一些特定的表,索引和序列定义H2 DB的设置。 @DataJpaTest使用自动配置的内存数据库。所以这是另一个问题:它是否会使用我的create.h2.sql文件来设置架构?例如。通过自动读取application-junit.properties?这是内容:

# database settings
spring.datasource.url=jdbc:h2:mem:testdb;Mode=Oracle;INIT=create schema if not exists testdb\\;SET SCHEMA testdb\\;runscript from 'classpath:create.h2.sql';
spring.datasource.username=sa
spring.datasource.password=
spring.datasource.platform=h2
spring.jpa.hibernate.ddl-auto=none
spring.datasource.continue-on-error=true

#datasource config
spring.database.driver-class-name=org.h2.Driver
spring.database.jndi-name=
spring.jpa.database-platform=org.hibernate.dialect.H2Dialect
spring.jpa.show-sql=true

如果您知道任何事情,请提前致谢,并且让我知道:)!

更新

这是我的SpringBootApplication类:

@EnableWebMvc
@SpringBootApplication
public class ApplicationStarter {

    public static void main(String[] args) {
        SpringApplication.run(ApplicationStarter.class, args);
    }
}

1 个答案:

答案 0 :(得分:2)

您的@SpringBootApplication上有@EnableWebMvc。当您使用切片注释(例如@DataJpaTest)时,Spring Boot会通过查看测试包@SpringBootConfiguration来查找要使用的上下文。如果找不到,则查找父包等。如果使用合理的包结构而无需进一步自定义,则测试会使用@SpringBootApplication作为根上下文。

@EnableWebMvc如果您不打算完全控制MVC设置see the documentation for more details,那就没用了。

在您的情况下,这会产生额外的副作用:现在每个测试都需要基于网络,因为您正在强制启动mvc设置。

TL;DR从未在您的应用上添加此类注释。只有你确实需要它才能把它放进去。