Meta-annotate @SpringBatchTest with @ExtendWith(SpringExtension.class)

Resolves #3647
This commit is contained in:
Mahmoud Ben Hassine
2020-04-30 17:33:37 +02:00
committed by GitHub
parent 60a99ca3fe
commit fe51fde3a0
4 changed files with 194 additions and 6 deletions

View File

@@ -85,6 +85,7 @@ allprojects {
jettisonVersion = '1.2' //? => upgrade to 1.4 and the build fails (deprecated anyway via xstream)
jmsVersion = '2.0.1'
junitVersion = '4.13'
junitJupiterVersion = '5.6.2'
log4jVersion = '2.13.0'
mysqlVersion = '8.0.18'
mockitoVersion = '3.1.0'
@@ -515,8 +516,11 @@ project('spring-batch-test') {
testCompile "org.hsqldb:hsqldb:$hsqldbVersion"
testCompile "org.mockito:mockito-core:$mockitoVersion"
testRuntime "org.junit.jupiter:junit-jupiter-engine:$junitJupiterVersion"
optional "org.aspectj:aspectjrt:$aspectjVersion"
optional "javax.batch:javax.batch-api:$javaxBatchApiVersion"
optional "org.junit.jupiter:junit-jupiter-api:$junitJupiterVersion"
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2018 the original author or authors.
* Copyright 2018-2020 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -22,11 +22,14 @@ import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import org.junit.jupiter.api.extension.ExtendWith;
import org.springframework.batch.test.JobLauncherTestUtils;
import org.springframework.batch.test.JobRepositoryTestUtils;
import org.springframework.batch.test.JobScopeTestExecutionListener;
import org.springframework.batch.test.StepScopeTestExecutionListener;
import org.springframework.test.context.TestExecutionListeners;
import org.springframework.test.context.junit.jupiter.SpringExtension;
/**
* Annotation that can be specified on a test class that runs Spring Batch based tests.
@@ -45,7 +48,7 @@ import org.springframework.test.context.TestExecutionListeners;
* </li>
* </ul>
* <p>
* A typical usage of this annotation is like:
* A typical usage of this annotation with JUnit 4 is like:
*
* <pre class="code">
* &#064;RunWith(SpringRunner.class)
@@ -79,6 +82,40 @@ import org.springframework.test.context.TestExecutionListeners;
* }
* </pre>
*
* For JUnit 5, this annotation can be used without having to manually register the
* {@link SpringExtension} since {@code @SpringBatchTest} is meta-annotated with
* {@code @ExtendWith(SpringExtension.class)}:
*
* <pre class="code">
* &#064;SpringBatchTest
* &#064;ContextConfiguration(classes = MyBatchJobConfiguration.class)
* public class MyBatchJobTests {
*
* &#064;@Autowired
* private JobLauncherTestUtils jobLauncherTestUtils;
*
* &#064;@Autowired
* private JobRepositoryTestUtils jobRepositoryTestUtils;
*
* &#064;BeforeEach
* public void clearJobExecutions() {
* this.jobRepositoryTestUtils.removeJobExecutions();
* }
*
* &#064;Test
* public void testMyJob() throws Exception {
* // given
* JobParameters jobParameters = this.jobLauncherTestUtils.getUniqueJobParameters();
*
* // when
* JobExecution jobExecution = this.jobLauncherTestUtils.launchJob(jobParameters);
*
* // then
* Assertions.assertEquals(ExitStatus.COMPLETED, jobExecution.getExitStatus());
* }
*
* }
* </pre>
* @author Mahmoud Ben Hassine
* @since 4.1
* @see JobLauncherTestUtils
@@ -94,5 +131,6 @@ import org.springframework.test.context.TestExecutionListeners;
listeners = {StepScopeTestExecutionListener.class, JobScopeTestExecutionListener.class},
mergeMode = TestExecutionListeners.MergeMode.MERGE_WITH_DEFAULTS
)
@ExtendWith(SpringExtension.class)
public @interface SpringBatchTest {
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2018 the original author or authors.
* Copyright 2018-2020 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -46,14 +46,14 @@ import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringRunner;
/**
* Test cases for usage of {@link SpringBatchTest} annotation.
* Test cases for usage of {@link SpringBatchTest} annotation with JUnit 4.
*
* @author Mahmoud Ben Hassine
*/
@RunWith(SpringRunner.class)
@SpringBatchTest
@ContextConfiguration(classes = SpringBatchTestTests.JobConfiguration.class)
public class SpringBatchTestTests {
@ContextConfiguration
public class SpringBatchTestJUnit4Tests {
@Autowired
private JobLauncherTestUtils jobLauncherTestUtils;

View File

@@ -0,0 +1,146 @@
/*
* Copyright 2020 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.batch.test;
import java.util.Arrays;
import javax.sql.DataSource;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.springframework.batch.core.ExitStatus;
import org.springframework.batch.core.Job;
import org.springframework.batch.core.JobExecution;
import org.springframework.batch.core.JobParameters;
import org.springframework.batch.core.StepExecution;
import org.springframework.batch.core.configuration.annotation.EnableBatchProcessing;
import org.springframework.batch.core.configuration.annotation.JobBuilderFactory;
import org.springframework.batch.core.configuration.annotation.JobScope;
import org.springframework.batch.core.configuration.annotation.StepBuilderFactory;
import org.springframework.batch.core.configuration.annotation.StepScope;
import org.springframework.batch.item.ItemReader;
import org.springframework.batch.item.support.ListItemReader;
import org.springframework.batch.repeat.RepeatStatus;
import org.springframework.batch.test.context.SpringBatchTest;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseBuilder;
import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseType;
import org.springframework.test.context.ContextConfiguration;
/**
* Test cases for usage of {@link SpringBatchTest} annotation with JUnit 5.
*
* @author Mahmoud Ben Hassine
*/
@SpringBatchTest
@ContextConfiguration
public class SpringBatchTestJUnit5Tests {
@Autowired
private JobLauncherTestUtils jobLauncherTestUtils;
@Autowired
private JobRepositoryTestUtils jobRepositoryTestUtils;
@Autowired
private ItemReader<String> stepScopedItemReader;
@Autowired
private ItemReader<String> jobScopedItemReader;
@BeforeEach
public void setUp() {
this.jobRepositoryTestUtils.removeJobExecutions();
}
@Test
public void testStepScopedItemReader() throws Exception {
Assertions.assertEquals("foo", this.stepScopedItemReader.read());
Assertions.assertEquals("bar", this.stepScopedItemReader.read());
Assertions.assertNull(this.stepScopedItemReader.read());
}
@Test
public void testJobScopedItemReader() throws Exception {
Assertions.assertEquals("foo", this.jobScopedItemReader.read());
Assertions.assertEquals("bar", this.jobScopedItemReader.read());
Assertions.assertNull(this.jobScopedItemReader.read());
}
@Test
public void testJob() throws Exception {
// given
JobParameters jobParameters = this.jobLauncherTestUtils.getUniqueJobParameters();
// when
JobExecution jobExecution = this.jobLauncherTestUtils.launchJob(jobParameters);
// then
Assertions.assertEquals(ExitStatus.COMPLETED, jobExecution.getExitStatus());
}
public StepExecution getStepExecution() {
StepExecution execution = MetaDataInstanceFactory.createStepExecution();
execution.getExecutionContext().putString("input.data", "foo,bar");
return execution;
}
public JobExecution getJobExecution() {
JobExecution execution = MetaDataInstanceFactory.createJobExecution();
execution.getExecutionContext().putString("input.data", "foo,bar");
return execution;
}
@Configuration
@EnableBatchProcessing
public static class JobConfiguration {
@Bean
public DataSource dataSource() {
return new EmbeddedDatabaseBuilder()
.setType(EmbeddedDatabaseType.HSQL)
.addScript("/org/springframework/batch/core/schema-drop-hsqldb.sql")
.addScript("/org/springframework/batch/core/schema-hsqldb.sql")
.build();
}
@Bean
@StepScope
public ItemReader<String> stepScopedItemReader(@Value("#{stepExecutionContext['input.data']}") String data) {
return new ListItemReader<>(Arrays.asList(data.split(",")));
}
@Bean
@JobScope
public ItemReader<String> jobScopedItemReader(@Value("#{jobExecutionContext['input.data']}") String data) {
return new ListItemReader<>(Arrays.asList(data.split(",")));
}
@Bean
public Job job(JobBuilderFactory jobBuilderFactory, StepBuilderFactory stepBuilderFactory) {
return jobBuilderFactory.get("job")
.start(stepBuilderFactory.get("step")
.tasklet((contribution, chunkContext) -> RepeatStatus.FINISHED)
.build())
.build();
}
}
}