Java - Spring boot - Integration test - TestEntityManager does not get injected

11,113

"I need to start my Spring boot server outside of this integration test, to have an instance running for all the integration tests (and not a new one at each test)."

You don't need to do this. When you run a suite of tests annotated with @SpringBootTest the context will get cached between tests. From the docs:

"Spring’s test framework will cache application contexts between tests. Therefore, as long as your tests share the same configuration (no matter how it’s discovered), the potentially time consuming process of loading the context will only happen once."

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

Share:
11,113
F.doe
Author by

F.doe

Updated on June 14, 2022

Comments

  • F.doe
    F.doe almost 2 years

    I've an integration test to test the REST end-points of my Spring boot server.

    I need to create some data (without using the REST end-points), so I'm trying to use a TestEntityManager, so I annotated my test class with @SpringBootTest. So far so good, the test starts the spring boot context, and so my server, and the test passes.

    Problem: I need to start my Spring boot server outside of this integration test, to have an instance running for all the integration tests (and not a new one at each test). To do so, I start the server using the spring-boot-maven-plugin in the pre-integration-test. So far so good, it starts. But then, to prevent my integration test from starting its own Spring boot server, I need to remove the @SpringBootTest annotation from my IT class.
    Then the problems arrive. Even with the annotation @AutoConfigureTestEntityManager, my TestEntityManager does not get injected anymore.

    Any idea ? Many thanks

    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)
    

    Here is the code

    @RunWith(SpringRunner.class)
    @ComponentScan(basePackages = {"be.mycompany"})
    @AutoConfigureTestEntityManager
    @Transactional
    //@SpringBootTest
    @DirtiesContext(classMode = DirtiesContext.ClassMode.AFTER_CLASS)
    public class MediaRestControllerIT extends AbstractIntegrationTest {
        @Autowired
        TestEntityManager testEntityManager;
    
        ...
    }
    
  • F.doe
    F.doe about 7 years
    Ok I'll give it a try, thanks. Btw, For my knowledge, what would be the way to get the TestEntityManager injected whithout using the SpringBootTest annotation? And why is the AutoConfigureTestEntityManager annotation no working ? Kind rgds.
  • PaulNUK
    PaulNUK about 7 years
    Just create a method in a configuration class which returns one and annotate it with @Bean I would guess. But you may get issues with having a real and a test entity manager in the same container, so you might have to use Spring profiles to control which is turned on and which is turned off. But the Spring Boot testing framework is excellent, I wouldn't fight against it. Of particular use may be the "testing in application slices" support. Why doesn't AutoConfigureTestEntityManager work ? Pass; maybe you need another annotation to turn on the processing of that annotation ?
  • PaulNUK
    PaulNUK about 7 years