Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

spring boot integration test - database not autowired with @WebMvcTest

I have this sprig boot ( version 1.5.6) application that uses the following:

  • spring boot starter data jpa (jpa repositories and entities)
  • spring boot starter data gemfire (no repository or entities)
  • spring boot starter data rest (for HAL support)

Now, I am creating the unit tests for this application. In one test case I have following annotation:

@RunWith(SpringRunner.class)
@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT, properties = { "spring.cloud.enabled=false" })

The test initializes the jpa repository correctly and I am able to test the same.

Then I have another test with following annotation:

@RunWith(SpringRunner.class)
@WebMvcTest(MyRestController.class)

This test sets up the Mockmvc but it does not initializes the JPA repositories. It only initialize the MVC part of configuration. But I need the JPA repositories to be initialized as well. I have test data setup with data.sql file which is loaded as in-memory H2 database. The error I am getting is:

org.springframework.beans.factory.NoSuchBeanDefinitionException: No bean named 'entityManagerFactory' available

I have tried multiple things which have not worked out:

  • Using both annotations does not work as the class can have only one "BootstrapWith" annotation.
  • @EnableJpaRepositories does not work
  • @AutoConfigureTestDatabase does not work

I do see the following while the context initialization:

.s.d.r.c.RepositoryConfigurationDelegate : Multiple Spring Data modules found, entering strict repository configuration mode!

Now since spring is able to autowire the jpa repository in the first test and it works fine in the application, I think it should be able to autowire the repository in webMvc test case as well.

I could create a configuration file and initialize the entity manager, data source, etc in the test package but if there is a way to autowire things with spring, then I don't want to manage that configuration.

Please suggest.

like image 228
PankajSays Avatar asked Mar 09 '23 03:03

PankajSays


1 Answers

I see you have the @WebMvcTest annotation. That particular one is meant to test only the web layer, it doesn't load the whole application context, only the web context. You probably need to switch to @SpringBootTest and @AutoConfigureMockMvc to test the whole stack.

The way you do JPA tests with Spring Boot is using the @DataJpaTest annotation. It automatically configures everything, provided that you have an in-memory DB in the classpath (if you use maven, make sure it's in the "testing" scope). It also provides the TestEntityManager, which is an implementation of JPA's EntityManager interface with some useful features for testing.

Example:

@RunWith(SpringRunner.class)
@DataJpaTest
pubic class EntityTest {
    @Autowired TestEntityManager entityManager;

    @Test
    public void saveShouldPersistData() throws Exception {
        User saved = entityManager.persistFlushFind(new User("username", "password"));
        assertNonNull(saved);
    }
}

And in your pom.xml you can add the H2 database (Spring Boot can configure Derby and HSQLDB automatically as well)

<dependency>
  <groupId>com.h2database</groupId>
  <artifactId>h2</artifactId>
  <scope>test</scope>
</dependency>
like image 83
SrThompson Avatar answered Apr 26 '23 06:04

SrThompson