在使用 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.
最佳答案
我已经设法找到解决方法。正如最新更新所述,无法使用@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/