Populate a database with TestContainers in a SpringBoot integration test

前端 未结 6 1892
自闭症患者
自闭症患者 2021-02-20 07:10

I am testing TestContainers and I would like to know how to populate a database executing a .sql file to create the structure and add some rows.

How to do it?

         


        
6条回答
  •  北荒
    北荒 (楼主)
    2021-02-20 07:51

    You can use DatabaseRider, which uses DBUnit behind the scenes, for populating test database and TestContainers as the test datasource. Following is a sample test, full source code is available on github here.

    @RunWith(SpringRunner.class)
    @SpringBootTest
    @DataJpaTest
    @AutoConfigureTestDatabase(replace = AutoConfigureTestDatabase.Replace.NONE) @ActiveProfiles("integration-test")
    @DBRider //enables database rider in spring tests 
    @DBUnit(caseInsensitiveStrategy = Orthography.LOWERCASE) //https://stackoverflow.com/questions/43111996/why-postgresql-does-not-like-uppercase-table-names
    public class SpringBootDBUnitIt {
    
        private static final PostgreSQLContainer postgres = new PostgreSQLContainer(); //creates the database for all tests on this file 
    
        @PersistenceContext
        private EntityManager entityManager;
    
        @Autowired
        private UserRepository userRepository;
    
    
        @BeforeClass
        public static void setupContainer() {
            postgres.start();
        }
    
        @AfterClass
        public static void shutdown() {
            postgres.stop();
        }
    
    
        @Test
        @DataSet("users.yml")
        public void shouldListUsers() throws Exception {
            assertThat(userRepository).isNotNull();
            assertThat(userRepository.count()).isEqualTo(3);
            assertThat(userRepository.findByEmail("springboot@gmail.com")).isEqualTo(new User(3));
        }
    
        @Test
        @DataSet("users.yml") //users table will be cleaned before the test because default seeding strategy
        @ExpectedDataSet("expected_users.yml")
        public void shouldDeleteUser() throws Exception {
            assertThat(userRepository).isNotNull();
            assertThat(userRepository.count()).isEqualTo(3);
            userRepository.delete(userRepository.findOne(2L));
            entityManager.flush();//can't SpringBoot autoconfigure flushmode as commit/always
            //assertThat(userRepository.count()).isEqualTo(2); //assertion is made by @ExpectedDataset
        }
    
        @Test
        @DataSet(cleanBefore = true)//as we didn't declared a dataset DBUnit wont clear the table
        @ExpectedDataSet("user.yml")
        public void shouldInsertUser() throws Exception {
            assertThat(userRepository).isNotNull();
            assertThat(userRepository.count()).isEqualTo(0);
            userRepository.save(new User("newUser@gmail.com", "new user"));
            entityManager.flush();//can't SpringBoot autoconfigure flushmode as commit/always
            //assertThat(userRepository.count()).isEqualTo(1); //assertion is made by @ExpectedDataset
        }
    
    }
    

    src/test/resources/application-integration-test.properties

    spring.datasource.url=jdbc:tc:postgresql://localhost/test
    spring.datasource.driverClassName=org.testcontainers.jdbc.ContainerDatabaseDriver
    spring.datasource.username=test
    spring.datasource.password=test
    spring.jpa.database-platform=org.hibernate.dialect.PostgreSQL9Dialect
    spring.jpa.hibernate.ddl-auto=create
    spring.jpa.show-sql=true
    #spring.jpa.properties.org.hibernate.flushMode=ALWAYS #doesn't take effect 
    spring.jpa.hibernate.naming-strategy=org.hibernate.cfg.ImprovedNamingStrategy
    spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.PostgreSQLDialect
    

    And finally the datasets:

    src/test/resources/datasets/users.yml

    users:
      - ID: 1
        EMAIL: "dbunit@gmail.com"
        NAME: "dbunit"
      - ID: 2
        EMAIL: "rmpestano@gmail.com"
        NAME: "rmpestano"
      - ID: 3
        EMAIL: "springboot@gmail.com"
        NAME: "springboot"
    

    src/test/resources/datasets/expected_users.yml

    users:
      - ID: 1
        EMAIL: "dbunit@gmail.com"
        NAME: "dbunit"
      - ID: 3
        EMAIL: "springboot@gmail.com"
        NAME: "springboot"
    

    src/test/resources/datasets/user.yml

    users:
      - ID: "regex:\\d+"
        EMAIL: "newUser@gmail.com"
        NAME: "new user"
    

提交回复
热议问题