spring-boot - 如何使用 junit5 jupiter 引擎运行 @SpringBatchTest
问题描述
我正在按照下面的链接编写端到端的春季批处理作业测试。
https://docs.spring.io/spring-batch/docs/current/reference/html/testing.html#endToEndTesting
这告诉您使用 Junit4 功能 @RunWith(SpringRunner.class) 注释您的测试类,并且我的测试用例使用junit5的老式引擎运行良好。
由于我的其他非批处理相关测试用例在 jupiter 引擎上运行,因此我想在端到端的 spring 批处理作业测试中使用相同的测试用例。如果我用@ExtendWith(SpringExtension.class) 替换@RunWith(SpringRunner.class),我可以看到没有一个自动装配字段被实例化并且具有空值。
由于我对春季批次和木星都是新手,所以我无法理解出了什么问题。
任何指针将不胜感激
junit测试用例示例代码
import com.zaxxer.hikari.HikariDataSource;
import lombok.extern.slf4j.Slf4j;
import org.junit.Test;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.extension.ExtendWith;
import org.junit.runner.RunWith;
import org.springframework.batch.core.JobExecution;
import org.springframework.batch.core.configuration.annotation.BatchConfigurer;
import org.springframework.batch.core.configuration.annotation.JobBuilderFactory;
import org.springframework.batch.core.configuration.annotation.StepBuilderFactory;
import org.springframework.batch.test.JobLauncherTestUtils;
import org.springframework.batch.test.JobRepositoryTestUtils;
import org.springframework.batch.test.context.SpringBatchTest;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.util.TestPropertyValues;
import org.springframework.context.ApplicationContextInitializer;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.annotation.Import;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit.jupiter.SpringExtension;
import org.springframework.test.context.junit4.SpringRunner;
import org.testcontainers.containers.PostgreSQLContainer;
import org.testcontainers.junit.jupiter.Container;
import org.testcontainers.junit.jupiter.Testcontainers;
import static org.assertj.core.api.Assertions.assertThat;
@Slf4j
@Testcontainers
@SpringBatchTest
@SpringBootTest
@RunWith(SpringRunner.class)
//@ExtendWith(SpringExtension.class)
@ContextConfiguration(initializers = {BatchJobConfigTest.Initializer.class})
@Import({LiquibaseConfigprimary.class, LiquibaseConfigsecondary.class})
public class BatchJobConfigTest {
@Container
private static final PostgreSQLContainer postgreSQLContainer = new PostgreSQLContainer("postgres:latest")
.withDatabaseName("dummy-db")
.withUsername("sa")
.withPassword("sa");
@Autowired
private JobLauncherTestUtils jobLauncherTestUtils;
@Autowired
@Qualifier("primaryDatasource")
private HikariDataSource primaryDatasource;
@Autowired
@Qualifier("secondaryDatasource")
private HikariDataSource secondaryDatasource;
@Autowired
private SecondaryRepository secondaryRepository;
@Autowired
private PrimaryRepository primaryRepository;
@Autowired
private JobRepositoryTestUtils jobRepositoryTestUtils;
@Autowired
private BatchConfigurer batchConfigurer;
@Autowired
private JobBuilderFactory jobBuilderFactory;
@Autowired
private StepBuilderFactory stepBuilderFactory;
@BeforeEach
void setup() {
secondaryRepository.deleteAll();
primaryRepository.deleteAll();
}
@Test
public void testJob() throws Exception {
assertThat(primaryRepository.findAll()).hasSize(1);
assertThat(secondaryRepository.findAll()).hasSize(0);
JobExecution jobExecution = jobLauncherTestUtils.launchJob();
assertThat(secondaryRepository.findAll()).hasSize(1);
assertThat(jobExecution.getExitStatus().getExitCode()).isEqualTo("COMPLETED");
}
static class Initializer implements ApplicationContextInitializer<ConfigurableApplicationContext> {
public void initialize(ConfigurableApplicationContext configurableApplicationContext) {
if (!postgreSQLContainer.isRunning())
postgreSQLContainer.start();
TestPropertyValues.of(
"spring.data.postgres.url=" + postgreSQLContainer.getJdbcUrl(),
"spring.data.postgres.username=" + postgreSQLContainer.getUsername(),
"spring.data.postgres.password=" + postgreSQLContainer.getPassword(),
"spring.data.postgres.host=localhost",
"spring.data.postgres.port=" + postgreSQLContainer.getFirstMappedPort(),
"spring.data.postgres.database=" + postgreSQLContainer.getDatabaseName()
).applyTo(configurableApplicationContext.getEnvironment());
TestPropertyValues.of(
"spring.datasource-secondary.jdbc-url=" + postgreSQLContainer.getJdbcUrl(),
"spring.datasource-secondary.username=" + postgreSQLContainer.getUsername(),
"spring.datasource-secondary.password=" + postgreSQLContainer.getPassword(),
"spring.datasource-secondary.driver-class-name=org.postgresql.Driver"
).applyTo(configurableApplicationContext.getEnvironment());
}
}
}
解决方案
你可以摆脱@RunWith(SpringRunner.class)
. 无需添加@ExtendWith(SpringExtension.class)
,因为@SpringBootTest
至少在当前版本的 Spring Boot 中已经添加了。
然后你要做的是改变:
import org.junit.Test;
进入
import org.junit.jupiter.api.Test;
因为这就是告诉 JUnit 平台运行 Jupiter 测试而不是 Vintage 测试的原因。希望这能解决您的问题。