【问题标题】:Spring Boot 1.4.2, hibernate 5.2.3, Junit Test of repository, @DataJpaTest Issue, version conflict?Spring Boot 1.4.2,hibernate 5.2.3,存储库的 Junit 测试,@DataJpaTest 问题,版本冲突?
【发布时间】:2017-05-06 01:00:16
【问题描述】:

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

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

    @Autowired
    private TestEntityManager entityManager;

    @Autowired
    private MyRepository repository;

但我得到以下异常:

java.lang.IllegalStateException: 无法加载 ApplicationContext 在 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);
    }
}

【问题讨论】:

  • 这里有很多问题,我想我们可以回答所有问题,但如果你能专注于一个问题会更容易。你想知道如何将TestEntityManagerSpringBootTest 一起使用吗?
  • 据我所知,如果我想测试存储库,我不需要加载整个 spring 上下文,所以我决定只使用@DataJpaTest,它只加载存储库测试所需的所有内容,并且不使用 SpringBootTest。所以我的问题是:为什么这对我不起作用?
  • 你还没有解释什么不起作用。如果你在 github 上分享一个项目,速度会快 10 倍。
  • 当我使用 @DataJpaTest 启动 JUnit 存储库测试时,我总是得到上述异常(有或没有 SpringBootTest):无法加载 ApplicationContext / 错误创建名为 'defaultServletHandlerMapping' / java.lang 的 bean。 IllegalArgumentException:需要 ServletContext 来配置默认 servlet 处理
  • 好的,我编辑了原始帖子并更改了问题的顺序以使事情更清楚。

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


【解决方案1】:

您的@SpringBootApplication 上有@EnableWebMvc。当您使用切片注释(例如@DataJpaTest)时,Spring Boot 通过查看测试包中的@SpringBootConfiguration 来查找要使用的上下文。如果它没有找到,它会在父包中查找,等等。有了一个合理的包结构并且没有进一步的定制,你的测试使用你的 @SpringBootApplication 作为根上下文。

@EnableWebMvc 如果您不打算完全控制 MVC 设置,see the documentation for more details 将毫无用处。

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

TL;DR 永远不要在你的应用程序上添加这样的注释。并且仅在您确实需要时才放置它。

【讨论】:

  • 感谢spring.io/guides/gs/serving-web-content 我还发现我必须添加spring-webmvc 才能使其在没有@EnableWebMvc 的情况下工作。现在异常消失了。
  • 我不知道你所说的“让它在没有的情况下工作”是什么意思,但我认为它不准确。我已经添加了一个文档链接,请看一下。
  • 非常感谢您的帮助,斯蒂芬!
  • 没有 spring-mvc 我得到了一些其他的异常,entityManagerFactory 丢失了。
  • 我们可能应该在聊天中讨论这个问题(我想我知道你的问题可能是什么)。加入我们on gitter if you want to discuss more。但您应该在该上下文中添加该注释。
猜你喜欢
  • 1970-01-01
  • 2015-06-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-06-26
  • 2023-03-03
  • 2019-03-28
相关资源
最近更新 更多