java - 在 bean 上使用 @PostConstruct 对 @SqlGroup 进行 Spring 测试

标签 java spring junit

在使用 Spring 5、Junit4.11 和 JDK8 运行一些集成测试之前,我尝试使用 @SqlGroup 执行一些 SQL 语句。

直到今天,当我在我的“ConfigurationComponent”bean 上添加一些初始配置时,一切都完美无缺,并带有注释@PostConstruct。

由于 @PostConstruct 方法调用依赖于数据库的 bean,测试失败,因为 hiberante(因此数据库)找不到预加载的模式。

在我调查时,我发现放在@SqlGroup 中的语句将在 ApplicationContext 初始化后执行,因此 @PostConstruct 在模式加载之前执行。

这是我的集成测试抽象类。

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = { "classpath:application-context-test.xml" })
@Transactional
@Rollback(true)
@SqlGroup({
        @Sql(executionPhase = ExecutionPhase.BEFORE_TEST_METHOD, scripts = {
                "classpath:db_config.sql",
                "classpath:consultas/setup_esquema_0.1.sql",
                "classpath:db_datos_iniciales.sql"}),
        @Sql(executionPhase = ExecutionPhase.AFTER_TEST_METHOD, scripts = "classpath:db_teardown.sql") })
public abstract class AbstractServiceTest {

    @BeforeClass
    public static void setUpBeforeClass() throws Exception {

    }

    @AfterClass
    public static void tearDownAfterClass() throws Exception {
    }

    @Before
    public abstract void setUp() throws Exception;

    @After
    public abstract void tearDown() throws Exception;

    public static Long randomId() {
        return new Long(Math.round(Math.random() * 1000));
    }

}

有问题的 bean

@Configuration
public class ConfigurationComponent {

    @Autowired
    Resources resources; // resources are retrieved from database.

    @PostConstruct
    public void startUp() throws VariableGlobalInexistenteException {
        Config.environment = resources
                .getWsaaEnv();
        Config.validation = resources
                .getWsaaEnvValidation();
    }

}

我找不到使用@SqlGroup 来解决这个问题的方法。是否有任何解决方案,一种改变生命周期并首先执行 sql 语句的方法?。 如您所见,我正在使用 ExecutionPhase.BEFORE_TEST_METHOD,没有 这种情况下的显式配置,如“ExecutionPhase.BEFORE_SETUP”。


更新 09-07-2018 - 看起来没有办法使用 @Sql 实现此目的:

Both @Sql and the calling of @PostConstruct are handled by Spring Framework rather than Spring Boot. Also, I believe this is working as designed. The default execution phase for @Sql is BEFORE_TEST_METHOD (the other option is AFTER_TEST_METHOD). The application context is refreshed, and therefore @PostConstruct is called, once for the whole test class (in fact it could be once for multiple test classes if they share the same configuration) which happens before individual test methods are called. In other words, you cannot use @Sql as a means of preparing the database for calls that are made in @PostConstruct.

Github @PostConstruct executed before @Sql

最佳答案

我已经设法找到解决方法。正如最新更新所述,无法使用@SqlGroup 实现所需的行为。我不得不使用以下方法,使用@BeforeClass 和@AfterClass:

@BeforeClass
public static void setUpBeforeClass() throws Exception {

    DriverManagerDataSource dataSource = getDataSource();
    Connection conn = dataSource.getConnection();
    ScriptUtils.executeSqlScript(conn, new ClassPathResource("db_config.sql"));
    ScriptUtils.executeSqlScript(conn, new ClassPathResource("consultas/setup_schema"));
    ScriptUtils.executeSqlScript(conn, new ClassPathResource("db_init.sql"));
    JdbcUtils.closeConnection(conn);

}

@AfterClass
public static void tearDownAfterClass() throws Exception {
    Connection conn = getDataSource().getConnection();
    ScriptUtils.executeSqlScript(conn, new ClassPathResource(
            "db_teardown.sql"));
    JdbcUtils.closeConnection(conn);
}

private static DriverManagerDataSource getDataSource() {
    DriverManagerDataSource dataSource = new DriverManagerDataSource();
    dataSource.setUrl(url);
    dataSource.setUsername(username);
    dataSource.setPassword(password);
    dataSource.setDriverClassName(driver);
    return dataSource;
}

删除了所有@SqlGroup 注释。这种方法非常简洁,因为 ScriptUtils 不需要太多依赖项即可运行。

关于java - 在 bean 上使用 @PostConstruct 对 @SqlGroup 进行 Spring 测试,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52121860/

相关文章:

java - 为什么调用static final变量时static block 没有先执行

java - 根据总点击次数更改按钮点击的内容

java - Spring Cloud AWS SQS 监听器不工作

java - 测试期间 spring webflux 中的全局异常处理

java - AssertJ 无法在没有规模的情况下断言 BigDecimal 相等

java - 在 Java Web 应用程序中打印

java - 如何使用 Webfirmframework 将组件添加到现有 HTML?

java - Quarkus:dockerfile.jvm 与 dockerfile.native

android - 在android应用中要进行哪些单元测试

java - jUnit 测试精神