如何在应用程序 运行 之前在 SpringBootTest 中执行代码?
How to execute code in a SpringBootTest before the Application is run?
我有一个Spring基于引导的命令行应用程序。该应用程序创建或删除数据库中的一些记录。它不是直接通过 JDBC 而是通过一个特殊的 API (实例变量 dbService
)。
应用程序 class 如下所示:
@SpringBootApplication
public class Application implements CommandLineRunner {
@Autowired
private DbService dbService;
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
@Override
public void run(String... args) {
// Do something via dbService based on the spring properties
}
}
现在我想创建一个 Spring 启动测试,该测试将 运行 整个应用程序具有专门为测试准备的配置。
I 运行 使用内存数据库 (H2) 进行测试,该数据库在测试开始时为空。因此,我想将一些记录插入到数据库中——作为测试的设置。必须执行插入记录的代码
加载 Spring 上下文之后——这样我就可以使用 bean dbService
.
在应用程序之前 运行 -- 这样应用程序 运行s 与准备好的数据库。
不知为何上面两点我没有做到
我目前的情况是这样的:
@SpringBootTest
@DirtiesContext(classMode = ClassMode.AFTER_CLASS)
@ActiveProfiles("specialtest")
public class MyAppTest {
@Autowired
private DbService dbService;
private static final Logger logger = LoggerFactory.getLogger(MyAppTest.class);
// The expectation is that this method is executed after the spring context
// has been loaded and all beans created, but before the Application class
// is executed.
@EventListener(ApplicationStartedEvent.class)
public void preparedDbForTheTest() {
// Create some records via dbService
logger.info("Created records for the test");
}
// This test is executed after the application has run. Here we check
// whether the DB contains the expected records.
@Test
public void testApplication() {
// Check the DB contents
}
}
我的问题是方法 preparedDbForTheTest
似乎根本没有执行。
根据 SpringBoot docs,事件 ApplicationReadyEvent
恰好在我要执行设置代码时发送。但是不知何故代码没有执行。
如果我用 @Before...
注释该方法(我尝试了它的几种变体)然后它会被执行,但是 在 应用程序 class 有 运行.
我做错了什么?
测试 类 不是 Spring-managed bean,因此 @EventListener
方法之类的东西将被忽略。
解决您问题的最常规方法是添加一些 @TestConfiguration
声明 @EventListener
:
@SpringBootTest
@DirtiesContext(classMode = ClassMode.AFTER_CLASS)
public class MyAppTest {
private static final Logger logger = LoggerFactory.getLogger(MyAppTest.class);
@Test
public void testApplication() {
}
@TestConfiguration
static class DatabasePreparation {
@EventListener(ApplicationStartedEvent.class)
public void preparedDbForTheTest() {
logger.info("Created records for the test");
}
}
}
A @TestConfiguration
是附加的,因此它将与应用程序的主要配置一起使用。 preparedDbForTheTest
方法现在将作为刷新测试应用程序上下文的一部分被调用。
请注意,由于应用程序上下文缓存,不会为每个测试调用此方法。它只会作为刷新上下文的一部分被调用,然后可以在多个测试之间共享。
我有一个Spring基于引导的命令行应用程序。该应用程序创建或删除数据库中的一些记录。它不是直接通过 JDBC 而是通过一个特殊的 API (实例变量 dbService
)。
应用程序 class 如下所示:
@SpringBootApplication
public class Application implements CommandLineRunner {
@Autowired
private DbService dbService;
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
@Override
public void run(String... args) {
// Do something via dbService based on the spring properties
}
}
现在我想创建一个 Spring 启动测试,该测试将 运行 整个应用程序具有专门为测试准备的配置。
I 运行 使用内存数据库 (H2) 进行测试,该数据库在测试开始时为空。因此,我想将一些记录插入到数据库中——作为测试的设置。必须执行插入记录的代码
加载 Spring 上下文之后——这样我就可以使用 bean
dbService
.在应用程序之前 运行 -- 这样应用程序 运行s 与准备好的数据库。
不知为何上面两点我没有做到
我目前的情况是这样的:
@SpringBootTest
@DirtiesContext(classMode = ClassMode.AFTER_CLASS)
@ActiveProfiles("specialtest")
public class MyAppTest {
@Autowired
private DbService dbService;
private static final Logger logger = LoggerFactory.getLogger(MyAppTest.class);
// The expectation is that this method is executed after the spring context
// has been loaded and all beans created, but before the Application class
// is executed.
@EventListener(ApplicationStartedEvent.class)
public void preparedDbForTheTest() {
// Create some records via dbService
logger.info("Created records for the test");
}
// This test is executed after the application has run. Here we check
// whether the DB contains the expected records.
@Test
public void testApplication() {
// Check the DB contents
}
}
我的问题是方法 preparedDbForTheTest
似乎根本没有执行。
根据 SpringBoot docs,事件 ApplicationReadyEvent
恰好在我要执行设置代码时发送。但是不知何故代码没有执行。
如果我用 @Before...
注释该方法(我尝试了它的几种变体)然后它会被执行,但是 在 应用程序 class 有 运行.
我做错了什么?
测试 类 不是 Spring-managed bean,因此 @EventListener
方法之类的东西将被忽略。
解决您问题的最常规方法是添加一些 @TestConfiguration
声明 @EventListener
:
@SpringBootTest
@DirtiesContext(classMode = ClassMode.AFTER_CLASS)
public class MyAppTest {
private static final Logger logger = LoggerFactory.getLogger(MyAppTest.class);
@Test
public void testApplication() {
}
@TestConfiguration
static class DatabasePreparation {
@EventListener(ApplicationStartedEvent.class)
public void preparedDbForTheTest() {
logger.info("Created records for the test");
}
}
}
A @TestConfiguration
是附加的,因此它将与应用程序的主要配置一起使用。 preparedDbForTheTest
方法现在将作为刷新测试应用程序上下文的一部分被调用。
请注意,由于应用程序上下文缓存,不会为每个测试调用此方法。它只会作为刷新上下文的一部分被调用,然后可以在多个测试之间共享。