问题描述
我有写入数据库的 Spring Batch 作业(它有一个带有 JpaItemWriter
的步骤).我有一个集成测试,如下所示:
I have Spring Batch job that writes to the database (it has a step with a JpaItemWriter
). I have an integration test such as follows:
@RunWith(SpringRunner.class)
@SpringBootTest
@ActiveProfiles("integrationTest")
public class LoadApplicationTests {
@Autowired
private Job job;
@Autowired
private JobRepository jobRepository;
@Autowired
private JobLauncher jobLauncher;
private JobLauncherTestUtils jobLauncherTestUtils;
@Before
public void setUp() throws IOException, java.text.ParseException, Exception {
jobLauncherTestUtils = new JobLauncherTestUtils();
jobLauncherTestUtils.setJob(job);
jobRepository = new MapJobRepositoryFactoryBean(new ResourcelessTransactionManager()).getObject();
jobLauncherTestUtils.setJobRepository(jobRepository);
jobLauncherTestUtils.setJobLauncher(jobLauncher);
}
@Test
public void testJob() throws Exception {
JobParametersBuilder j = new JobParametersBuilder();
JobParameters jobParameters = j.addDate("runDate", new Date())
.addString("file", testFile.getAbsolutePath())
.addString("override", "false")
.addString("weekly", "false")
.toJobParameters();
JobExecution jobExecution = jobLauncherTestUtils.launchJob(jobParameters);
Assert.assertEquals("COMPLETED", jobExecution.getExitStatus().getExitCode());
}
}
在测试中运行作业时,它会提交到数据库.如何防止提交到数据库?通常,我可以在每次测试后添加 @Transactional
来回滚事务.但是,当我将注释添加到测试类时,我收到:
When running the job in the test, it commits to the database. How can I prevent committing to the database? Normally, I could add @Transactional
to rollback the transaction after each test. However, when I add the annotation the test class, I receive:
java.lang.IllegalStateException: Existing transaction detected in JobRepository. Please fix this and try again (e.g. remove @Transactional annotations from client).
更新
我尝试将 @Rollback
添加到测试类.但是,JpaItemWriter
仍然提交.
I have tried to add @Rollback
to the test class. However, the JpaItemWriter
still commits.
以下是应用程序代码中事务管理器的配置:
Here's the configuration for the transaction manager in the application code:
@Bean
public PlatformTransactionManager transactionManager(EntityManagerFactory entityManagerFactory) {
JpaTransactionManager transactionManager = new JpaTransactionManager();
transactionManager.setEntityManagerFactory(entityManagerFactory);
return transactionManager;
}
@Bean
public Step stepLoadFile(StepBuilderFactory stepBuilderFactory,
PlatformTransactionManager transactionManager,
ItemReader<MyClass> reader, ItemProcessor<MyClass,
MyClass> processor,
ItemWriter<MyClass> writer,
ReadFailureHandler readListenerSupport,
WriteFailureHandler writeListenerSupport) {
Step step = stepBuilderFactory.get("stepPersistFile")
.transactionManager(transactionManager)
.<MyClass, MyClass> chunk(1000)
.reader(reader)
.processor(processor)
.listener(writeListenerSupport)
.listener(readListenerSupport)
.writer(writer)
.build();
return step;
}
推荐答案
@DirtiesContext(classMode = AFTER_EACH_TEST_METHOD)
可能是你要找的,也是我过去测试的时候用过的改变数据库记录的程序.基于 Spring Docs, @DirtiesContext
是一个
@DirtiesContext(classMode = AFTER_EACH_TEST_METHOD)
may be what you are looking for, and is what I have used in the past when testing programs which alter database records. Based on the Spring Docs, @DirtiesContext
is a
测试注解,表明与测试关联的 ApplicationContext 是脏的,因此应该关闭并从上下文缓存中删除.如果测试修改了上下文,请使用此注释——例如,通过修改单例 bean 的状态、修改嵌入式数据库的状态等.请求相同上下文的后续测试将被提供一个新的上下文.
否则,基于@Dan 的回答,TestTransaction
可能允许在用 @Test
、@Before 和
@After
.见 此处了解更多信息.
Otherwise, building off of @Dan's answer,
TestTransaction
may allow for more explicit control of your test transactions within methods annotated with @Test
, @Before
, and @After
. See here for more info.
这篇关于Spring Batch - 如何使用 jobLauncherTestUtils 防止数据库提交的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!