Java - Spring boot - 集成测试 - TestEntityManager 没有被注入

Posted

技术标签:

【中文标题】Java - Spring boot - 集成测试 - TestEntityManager 没有被注入【英文标题】:Java - Spring boot - Integration test - TestEntityManager does not get injected 【发布时间】:2017-08-04 14:14:36 【问题描述】:

我有一个集成测试来测试我的 Spring 引导服务器的 REST 端点。

我需要创建一些数据(不使用 REST 端点),所以我尝试使用 TestEntityManager, 所以我用@SpringBootTest 注释了我的测试类。到目前为止一切顺利,测试启动了 spring boot 上下文,所以我的服务器,测试通过了。

问题: 我需要在此集成测试之外启动我的 Spring 引导服务器,以便为所有集成测试运行一个实例(而不是在每个测试中运行一个新实例)。 为此,我在预集成测试中使用 spring-boot-maven-plugin 启动服务器。 到目前为止一切顺利,它开始了。但是,为了防止我的集成测试启动它自己的 Spring 引导服务器,我需要从我的 IT 类中删除 @SpringBootTest 注释。 然后问题就来了。 即使使用注释 @AutoConfigureTestEntityManager,我的 TestEntityManager 也不会再被注入。

有什么想法吗? 非常感谢

2017-03-14 10:42:31,371 ERROR o.s.test.context.TestContextManager - Caught exception while allowing TestExecutionListener [org.springframework.test.context.support.DependencyInjectionTestExecutionListener@56bf6f1e] to prepare test instance [be.mycompany.controllers.mediaRestControllerIT@340ef431]
java.lang.IllegalStateException: Failed to load ApplicationContext
    at org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate.loadContext(DefaultCacheAwareContextLoaderDelegate.java:124)
    at org.springframework.test.context.support.DefaultTestContext.getApplicationContext(DefaultTestContext.java:83)
    ....
Caused by: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'testEntityManager' defined in class path resource [org/springframework/boot/test/autoconfigure/orm/jpa/TestEntityManagerAutoConfiguration.class]: Unsatisfied dependency expressed through method 'testEntityManager' parameter 0; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'javax.persistence.EntityManagerFactory' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: 
    ... 26 common frames omitted
Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'javax.persistence.EntityManagerFactory' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: 
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.raiseNoMatchingBeanFound(DefaultListableBeanFactory.java:1486)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1104)

这里是代码

@RunWith(SpringRunner.class)
@ComponentScan(basePackages = "be.mycompany")
@AutoConfigureTestEntityManager
@Transactional
//@SpringBootTest
@DirtiesContext(classMode = DirtiesContext.ClassMode.AFTER_CLASS)
public class MediaRestControllerIT extends AbstractIntegrationTest 
    @Autowired
    TestEntityManager testEntityManager;

    ...

【问题讨论】:

【参考方案1】:

“我需要在此集成测试之外启动我的 Spring 引导服务器,以便为所有集成测试运行一个实例(而不是在每个测试中都运行一个新实例)。”

您不需要这样做。当您运行一组使用 @SpringBootTest 注释的测试时,上下文将在测试之间缓存。来自文档:

“Spring 的测试框架会在测试之间缓存应用程序上下文。因此,只要你的测试共享相同的配置(无论它是如何被发现的),加载上下文的潜在耗时过程只会发生一次。”

https://docs.spring.io/spring-boot/docs/current/reference/html/boot-features-testing.html

【讨论】:

好的,我试试,谢谢。顺便说一句,据我所知,在不使用 SpringBootTest 注释的情况下注入 TestEntityManager 的方法是什么?为什么 AutoConfigureTestEntityManager 注释不起作用?善良的 rgds。 只需在配置类中创建一个方法,该方法返回一个并用@Bean 注释我猜。但是你可能会遇到在同一个容器中拥有一个真实的实体管理器和一个测试实体管理器的问题,因此你可能必须使用 Spring 配置文件来控制哪些是打开的,哪些是关闭的。但是 Spring Boot 测试框架非常好,我不会反对它。特别有用的可能是“应用程序切片中的测试”支持。为什么 AutoConfigureTestEntityManager 不起作用?经过;也许您需要另一个注释来打开该注释的处理? 这可能也有帮助:devthoughts.pl/2016/08/02/datajpatest-from-spring-boot

以上是关于Java - Spring boot - 集成测试 - TestEntityManager 没有被注入的主要内容,如果未能解决你的问题,请参考以下文章

在 Spring Boot 应用程序中分离集成测试

Spring Boot教程14——集成测试

Elasticsearch Spring boot 集成测试

在java Spring Boot中,如何在集成测试中将内存中的LDAPConnection对象传递给ldapService?

使用 Spring Boot 在单元测试中配置集成测试或使用 Spring JDBC?

Spring Boot 集成测试抛出错误“java.lang.IllegalStateException: Timeout on blocking read for 5000 MILLISECONDS