我们有一个 Spring Bean 在启动 Spring 启动应用程序时做一些初始化工作。为此,应用程序注册一个ApplicationListener<ApplicationReadyEvent>
,该查询数据库并处理数据。
为了测试这个过程,我们必须在数据库中注入测试数据。我们的第一次尝试是使用特定于测试的ApplicationListener<ApplicationStartedEvent>
初始化数据库。这有效,但是,代码看起来相当讨厌。这个想法是使用@Sql
注释来加载初始数据。
这不符合预期,因为数据是在发布ApplicationReadyEvent
后注入的。我找不到更改@Sql
数据写入数据库的阶段的方法。
有没有办法确保@Sql
的数据是在发布ApplicationReadyEvent
之前写入的?该测试目前以其他方式注释为与SpringRunner
、@DataJpaTest
和@DirtiesContext
一起运行。
编辑:提供代码
ApplicationListener ist提供了如下:
@Component
public class ApplicationStartup implements ApplicationListener<ApplicationReadyEvent> {
@Override
public void onApplicationEvent(final ApplicationReadyEvent event) {
// Do someting with SQL-Data
}
}
虽然测试看起来像这样:
@RunWith(SpringRunner.class)
@ComponentScan
@Import(SomeTestConfig.class)
@DataJpaTest
//@SQL("/somedata.sql")
public class SomeTest {
@Test
public void test() {
// Assert ApplicationListener has run
}
}
测试配置如下:
@TestConfiguration
@Profile(ReplayTest.PROFILE_SOME_TEST)
class SomeTestConfig {
@Bean
public ApplicationListener<ApplicationStartedEvent> testSetupBean() {
return new ApplicationListener<ApplicationStartedEvent>() {
// Insert data within onApplicationEvent-Method
};
}
}
如果我取消注释@SQL并注释掉@Import
,则测试数据从测试本身中可见,但在应用程序侦听器中不可见。
您可以使用@Order
注释。您可以使用它批注应用程序侦听器和测试。默认情况下,此优先级最低。因此,您应该为应用程序侦听器提供较高的优先级,为测试提供最低的优先级。
听者:
@Override
@Order(Ordered.HIGHEST_PRECEDENCE)
public void onApplicationEvent(ApplicationReadyEvent event) {
System.out.println("...publishing application event");
}
测试:
@Test
@Sql(scripts = "test.sql")
@Order
public void test() {
System.out.println("...loading data");
}