BYTECODES

如何做集成测试(集成数据库做测试)

虽然unit test单元测试可以帮助我们测试很多业务场景,但是鉴于java很多操作还是增删改差,那测试数据库上的存取操作以验证是否存入或取出想要的数据,还是很必要的。传统使用h2来做内存数据库,但缺点很多,最大的缺点应该是数据库兼容性问题。这个就不细说了,我们是用testcontainers解决方案。一个具体的示例如下:


先写一个测试用的基类

package repositories;

import org.springframework.context.ApplicationContextInitializer;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.support.TestPropertySourceUtils;
import org.testcontainers.containers.PostgreSQLContainer;
import org.testcontainers.junit.jupiter.Container;
import org.testcontainers.junit.jupiter.Testcontainers;

@Testcontainers
@ContextConfiguration(initializers = DatabaseTest.DataSourceInitializer.class)
public abstract class DatabaseTest {

    @Container
    private static final PostgreSQLContainer<?> database = new PostgreSQLContainer<>("postgres:14.4-alpine");

    public static class DataSourceInitializer implements ApplicationContextInitializer<ConfigurableApplicationContext> {

        @Override
        public void initialize(ConfigurableApplicationContext applicationContext) {
            TestPropertySourceUtils.addInlinedPropertiesToEnvironment(
                    applicationContext,
                    "spring.test.database.replace=none",
                    "spring.datasource.url=" + database.getJdbcUrl(),
                    "spring.datasource.username=" + database.getUsername(),
                    "spring.datasource.password=" + database.getPassword()
            );
        }
    }
}

具体的一个测试类如下:

package repositories;

import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest;
import org.springframework.boot.test.mock.mockito.MockBean;
import org.springframework.test.context.jdbc.Sql;
import domain.Account;
import domain.AccountRepository;
import domain.Role;

@DataJpaTest
public class AccountRepositoryTest extends DatabaseTest {
    @Autowired
    private AccountRepository accountRepository;

    @Test
    @Sql("classpath:sql/initAccount.sql")
    public void shouldGetSuccess() {
        Account account = accountRepository.findByUserId("1");
        Assertions.assertEquals(Role.USER, account.getRole());
    }
}