簡體   English   中英

Spring 測試 @SqlGroup 和 @PostConstruct on bean

[英]Spring Test @SqlGroup with @PostConstruct on bean

在使用Spring 5、Junit4.11 和 JDK8運行一些集成測試之前,我試圖用 @SqlGroup 執行一些 SQL 語句

直到今天,當我在“ConfigurationComponent”bean 上添加了一些初始配置時,一切都完美無缺,並帶有 @PostConstruct 注釋。

當@PostConstruct 方法調用依賴於數據庫的 bean 時,測試失敗,因為 hiberante(因此數據庫)找不到預加載的模式。

經過調查,發現@SqlGroup 中的語句會在ApplicationContext 初始化之后執行,所以@PostConstruct 在schema 加載之前執行。

這是我的集成測試抽象類。

@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));
    }

}

冒犯的豆

@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”。


2018 年 9 月 7 日更新 - 使用 @Sql 似乎無法實現此目的:

@Sql 和 @PostConstruct 的調用都由 Spring Framework 處理,而不是 Spring Boot。 另外,我相信這是按設計工作的。 @Sql 的默認執行階段是 BEFORE_TEST_METHOD(另一個選項是 AFTER_TEST_METHOD)。 應用程序上下文被刷新,因此 @PostConstruct 被調用一次,整個測試類(實際上,如果多個測試類共享相同的配置,它可能是一次),這發生在調用單個測試方法之前。 換句話說,您不能使用@Sql 作為為@PostConstruct 中進行的調用准備數據庫的方法。

Github @PostConstruct 在 @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 不需要太多的依賴來運行。

另一種解決方法是實施 CommandLineRunner。

@Component
public class ConfigurationInitRunner implements CommandLineRunner {

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

    @Override
    public void run(String... strings) throws Exception {
        Config.environment = resources.getWsaaEnv();
        Config.validation = resources.getWsaaEnvValidation();
    }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM