17

I am using the @DataJpaTest from Spring for my test which will then use H2 as in memory database as described here . I'm also using Flyway for production. However once the test starts FLyway kicks in and reads the SQL file. How can I exclude the FlywayAutoConfiguration and keep the rest as described here in spring documentation in order to let Hibernate create the tables in H2 for me?

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

    @Autowired
    private TestEntityManager entityManager;

    @Autowired
    private MyRepository triggerRepository;
}
LAC
  • 852
  • 4
  • 11
  • 31

8 Answers8

7

Have you tried the @OverrideAutoConfiguration annotation? It says it "can be used to override @EnableAutoConfiguration". I'm assuming that from there you can somehow exclude FlywayAutoConfiguration like so:

@EnableAutoConfiguration(exclude=FlywayAutoConfiguration.class)
Alex Shesterov
  • 26,085
  • 12
  • 82
  • 103
Livia Moroianu
  • 906
  • 7
  • 6
  • The annotation says it can be used in combination with @ ImportAutoConfiguration. The exclusion using @ EnableAutoConfiguration doesn't work. I tried to add every auto-configuration class except for the Flyway just to see whether it works that way or not. Some parts are working (e.g. Flyway doesn't kick in anymore) some don't. E.g the Transaction is not working and I have to use @ Transactional. Also the Tables are not created by Hibernate automatically. There are missing parts and actually I prefer to get the exclusion running. I'm using the following config now. – LAC Aug 31 '16 at 20:32
  • @ RunWith(SpringRunner.class) @ SpringBootTest @ OverrideAutoConfiguration(enabled = false) @ ImportAutoConfiguration(value = { CacheAutoConfiguration.class, JpaRepositoriesAutoConfiguration.class, DataSourceAutoConfiguration.class, DataSourceTransactionManagerAutoConfiguration.class, HibernateJpaAutoConfiguration.class, TransactionAutoConfiguration.class, TestDatabaseAutoConfiguration.class, TestEntityManagerAutoConfiguration.class }) @ Transactional – LAC Aug 31 '16 at 20:33
  • 1
    I've raised https://github.com/spring-projects/spring-boot/issues/6809 to see what we can do to improve things here. – Phil Webb Sep 02 '16 at 09:01
  • @PhilWebb that's great ;) but do you have a workaround for now? – LAC Sep 05 '16 at 13:40
  • Not yet I'm afraid. – Phil Webb Sep 06 '16 at 17:47
4

Adding the dependency on an in-memory database to my build.gradle
e.g. testRuntime "com.h2database:h2:1.4.194"

And adding flyway.enabled=false to application.properties in src/test/resources worked for me.

Trevor Gowing
  • 2,236
  • 22
  • 25
  • Thank you! That worked for me. The key here is to instruct flyway to be disabled (as you answered)! e.g. flyway.enabled=false – user1697575 Dec 19 '18 at 15:45
2

I am converting an old JDBC app into a spring-data-jpa app and I'm working on the first tests now. I kept seeing a security module instantiation error from spring-boot as it tried to bootstrap the security setup, even though @DataJpaTest should theoretically be excluding it.

My problem with the security module probably stems from the pre-existing implementation which I inherited using PropertySourcesPlaceholderConfigurer (via my PropertySpringConfig import below)

Following the docs here:

http://docs.spring.io/spring-boot/docs/1.4.x/reference/htmlsingle/#test-auto-configuration

and your comments on @LiviaMorunianu's answer, I managed to work my way past every spring-boot exception and get JUnit to run with an auto-configured embedded DB.

My main/production spring-boot bootstrap class bootstraps everything including the stuff I want to exclude from my tests. So instead of using @DataJpaTest, I copied much of what it is doing, using @Import to bring in the centralized configurations that every test / live setup will use.

I also had issues because of the package structure I use, since initially I was running the test which was based in com.mycompany.repositories and it didn't find the entities in com.mycompany.entities.

Below are the relevant classes.

JUnit Test

@RunWith(SpringRunner.class)
@Transactional
@Import({TestConfiguration.class, LiveConfiguration.class})
public class ForecastRepositoryTests {    

    @Autowired
    ForecastRepository repository;
    Forecast forecast; 

    @Before
    public void setUp() {
        forecast = createDummyForecast(TEST_NAME, 12345L);
    }

    @Test
    public void testFindSavedForecastById() {
        forecast = repository.save(forecast);
        assertThat(repository.findOne(forecast.getId()), is(forecast));
    }

Live Configuration

@Configuration
@EnableJpaRepositories(basePackages = {"com.mycompany.repository"})
@EntityScan(basePackages = {"com.mycompany.entity"})
@Import({PropertySpringConfig.class})
public class LiveConfiguration {}

Test Configuration

@OverrideAutoConfiguration(enabled = false)
@ImportAutoConfiguration(value = {
        CacheAutoConfiguration.class,
        JpaRepositoriesAutoConfiguration.class,
        DataSourceAutoConfiguration.class,
        DataSourceTransactionManagerAutoConfiguration.class,
        HibernateJpaAutoConfiguration.class,
        TransactionAutoConfiguration.class,
        TestDatabaseAutoConfiguration.class,
        TestEntityManagerAutoConfiguration.class })
public class TestConfiguration {
    // lots of bean definitions...
}

PropertySpringConfig

@Configuration
public class PropertySpringConfig {
    @Bean
    static PropertySourcesPlaceholderConfigurer propertySourcesPlaceholderConfigurer() 
                throws IOException {
        return new CorePropertySourcesPlaceholderConfigurer(
            System.getProperties());
    }
}
Adam
  • 5,215
  • 5
  • 51
  • 90
  • 1
    I had a nice `@DataJpaTest` working (spring 5.04) and testing only my simple repository. Then I added a dependency to SchemaRegistryClient and my totally unrelated JPA test stopped working. It was suddenly complaining of a missing CacheManager bean ... I ended up stacking a similar pile of annotation and configuration class to get it back working :-/ Hope the @DataJpaTest annotation will be improved – Ghurdyl Apr 25 '18 at 15:05
2

In my particular case, i needed to disable the FlywayDB on in-memory integration tests. These are using a set of spring annotations for auto-configuring a limited applicationContext.

@ImportAutoConfiguration(value = TestConfig.class, exclude = FlywayAutoConfiguration.class)

the exclude could effectively further limit the set of beans initiated for this test

padisah
  • 41
  • 5
  • The annotation has changed exactly because of this question. At the time of writing this the option of exclusion didn't exist, therefore this issue was created on Spring boot side: https://github.com/spring-projects/spring-boot/issues/6809 – LAC Jul 17 '18 at 18:53
  • I am happy to hear this. I just wanted to help out followers, and this question has no accepted answer yet. – padisah Jul 18 '18 at 19:59
1

I had the same problem with my DbUnit tests defined in Spock test classes. In my case I was able to disable the Flyway migration and managed to initialize the H2 test database tables like this:

@SpringBootTest(classes = MyApplication.class, webEnvironment = SpringBootTest.WebEnvironment.NONE,
    properties = ["flyway.enabled=false", "spring.datasource.schema=db/migration/h2/V1__init.sql"])

I added this annotation to my Spock test specification class. Also, I was only able to make it work if I also added the context configuration annotation:

@ContextConfiguration(classes = MyApplication.class)
virgium03
  • 627
  • 1
  • 5
  • 14
1

I resolved the same issue by excluding the autoconfiguration from my application definition, i.e.

@SpringBootApplication(exclude = {FlywayAutoConfiguration.class})
public class Application {
    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }
}
Kristoffer
  • 251
  • 2
  • 10
1

you can also sue the following annotation:

@RunWith(SpringRunner.class)
@DataJpaTest(excludeAutoConfiguration = {MySqlConfiguration.class, ...})
public class TheClassYouAreUnitTesting {
}
1

You can just disable it in your test yaml file:

flyway.enabled: false

Bob Dalgleish
  • 8,167
  • 4
  • 32
  • 42
bitmountain
  • 95
  • 2
  • 9