为了账号安全,请及时绑定邮箱和手机立即绑定

Spring 测试 @SqlGroup 和 @PostConstruct on bean

Spring 测试 @SqlGroup 和 @PostConstruct on bean

MMTTMM 2021-08-25 10:09:04
在使用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));    }}我找不到使用@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 中进行的调用准备数据库的方法。
查看完整描述

2 回答

?
largeQ

TA贡献2039条经验 获得超7个赞

另一种解决方法是实施 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();

    }

}


查看完整回答
反对 回复 2021-08-25
?
九州编程

TA贡献1785条经验 获得超4个赞

我设法找到了解决方法。正如最新更新所述,使用@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 不需要太多的依赖来运行。


查看完整回答
反对 回复 2021-08-25
  • 2 回答
  • 0 关注
  • 220 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信