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;
...
}
TestRestTemplate. As explained above, for integrating testing of a spring-boot application, we need to use @SpringBootTest. spring-boot also does provide other classes like TestRestTemplate to test the REST APIs. Like RestTemplate class, it also does have methods getForObject(), postForObject(), exchange(), etc..
Spring Boot provides a number of useful tools for testing your application. The spring-boot-starter-test POM provides Spring Test, JUnit, Hamcrest and Mockito dependencies.
The first is you need to annotate your tests with the @RunWith annotation and specify that you want to run it with the SpringJUnit4ClassRunner. class . The second is you need to add the @SpringApplicationConfiguration annotation and provide your main Spring Boot class for your application.
@SpringBootTest is a primary annotation to create unit and integration tests in Spring Boot applications. The annotation enables additional features such as custom environment properties, different web environment modes, random ports, TestRestTemplate and WebTestClient beans.
"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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With