From 05bbd3f7ea8b909942629e5bdaae94dfdfa2a7f1 Mon Sep 17 00:00:00 2001 From: Mahmoud Ben Hassine Date: Wed, 16 Nov 2022 14:20:48 +0100 Subject: [PATCH] Remove dependency autowiring in test utilities Issue #4233 --- .../sample/config/JobRunnerConfiguration.java | 11 +++++--- .../sample/JobStepFunctionalTests-context.xml | 2 ++ .../batch/test/JobLauncherTestUtils.java | 4 +-- .../batch/test/JobRepositoryTestUtils.java | 14 ---------- .../BatchTestContextBeanPostProcessor.java | 22 ++++++++++++++++ .../batch/test/context/SpringBatchTest.java | 26 +++++++++++-------- .../batch/test/JobLauncherTestUtilsTests.java | 6 +++-- ...copeAnnotatedListenerIntegrationTests.java | 13 +++++++--- .../src/test/resources/job-runner-context.xml | 6 +++-- 9 files changed, 65 insertions(+), 39 deletions(-) diff --git a/spring-batch-samples/src/test/java/org/springframework/batch/sample/config/JobRunnerConfiguration.java b/spring-batch-samples/src/test/java/org/springframework/batch/sample/config/JobRunnerConfiguration.java index b1c2646cc..50715a59d 100644 --- a/spring-batch-samples/src/test/java/org/springframework/batch/sample/config/JobRunnerConfiguration.java +++ b/spring-batch-samples/src/test/java/org/springframework/batch/sample/config/JobRunnerConfiguration.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2021 the original author or authors. + * Copyright 2012-2022 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. @@ -15,6 +15,8 @@ */ package org.springframework.batch.sample.config; +import org.springframework.batch.core.launch.JobLauncher; +import org.springframework.batch.core.repository.JobRepository; import org.springframework.batch.test.JobLauncherTestUtils; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @@ -28,8 +30,11 @@ import org.springframework.context.annotation.Configuration; public class JobRunnerConfiguration { @Bean - public JobLauncherTestUtils utils() throws Exception { - return new JobLauncherTestUtils(); + public JobLauncherTestUtils utils(JobRepository jobRepository, JobLauncher jobLauncher) { + JobLauncherTestUtils jobLauncherTestUtils = new JobLauncherTestUtils(); + jobLauncherTestUtils.setJobRepository(jobRepository); + jobLauncherTestUtils.setJobLauncher(jobLauncher); + return jobLauncherTestUtils; } } diff --git a/spring-batch-samples/src/test/resources/org/springframework/batch/sample/JobStepFunctionalTests-context.xml b/spring-batch-samples/src/test/resources/org/springframework/batch/sample/JobStepFunctionalTests-context.xml index 5df2b33cc..ad024fcd5 100644 --- a/spring-batch-samples/src/test/resources/org/springframework/batch/sample/JobStepFunctionalTests-context.xml +++ b/spring-batch-samples/src/test/resources/org/springframework/batch/sample/JobStepFunctionalTests-context.xml @@ -7,5 +7,7 @@ + + diff --git a/spring-batch-test/src/main/java/org/springframework/batch/test/JobLauncherTestUtils.java b/spring-batch-test/src/main/java/org/springframework/batch/test/JobLauncherTestUtils.java index b13364cbb..bc8b39f8e 100644 --- a/spring-batch-test/src/main/java/org/springframework/batch/test/JobLauncherTestUtils.java +++ b/spring-batch-test/src/main/java/org/springframework/batch/test/JobLauncherTestUtils.java @@ -22,6 +22,7 @@ import java.util.Map; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; + import org.springframework.batch.core.Job; import org.springframework.batch.core.JobExecution; import org.springframework.batch.core.JobParameter; @@ -35,7 +36,6 @@ import org.springframework.batch.core.launch.JobLauncher; import org.springframework.batch.core.repository.JobRepository; import org.springframework.batch.core.step.StepLocator; import org.springframework.batch.item.ExecutionContext; -import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.ApplicationContext; import org.springframework.lang.Nullable; @@ -94,7 +94,6 @@ public class JobLauncherTestUtils { * The {@link JobRepository} to use for creating new {@link JobExecution} instances. * @param jobRepository a {@link JobRepository} */ - @Autowired public void setJobRepository(JobRepository jobRepository) { this.jobRepository = jobRepository; } @@ -117,7 +116,6 @@ public class JobLauncherTestUtils { * A {@link JobLauncher} instance that can be used to launch jobs. * @param jobLauncher a job launcher */ - @Autowired public void setJobLauncher(JobLauncher jobLauncher) { this.jobLauncher = jobLauncher; } diff --git a/spring-batch-test/src/main/java/org/springframework/batch/test/JobRepositoryTestUtils.java b/spring-batch-test/src/main/java/org/springframework/batch/test/JobRepositoryTestUtils.java index 5623c6fab..9aea7ff7b 100644 --- a/spring-batch-test/src/main/java/org/springframework/batch/test/JobRepositoryTestUtils.java +++ b/spring-batch-test/src/main/java/org/springframework/batch/test/JobRepositoryTestUtils.java @@ -15,15 +15,11 @@ */ package org.springframework.batch.test; -import java.sql.ResultSet; -import java.sql.SQLException; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.List; -import javax.sql.DataSource; - import org.springframework.batch.core.JobExecution; import org.springframework.batch.core.JobInstance; import org.springframework.batch.core.JobParameter; @@ -34,16 +30,7 @@ import org.springframework.batch.core.repository.JobExecutionAlreadyRunningExcep import org.springframework.batch.core.repository.JobInstanceAlreadyCompleteException; import org.springframework.batch.core.repository.JobRepository; import org.springframework.batch.core.repository.JobRestartException; -import org.springframework.batch.core.repository.dao.AbstractJdbcBatchMetadataDao; -import org.springframework.beans.factory.InitializingBean; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.dao.DataAccessException; -import org.springframework.jdbc.core.JdbcOperations; -import org.springframework.jdbc.core.JdbcTemplate; -import org.springframework.jdbc.core.RowMapper; import org.springframework.lang.Nullable; -import org.springframework.util.Assert; -import org.springframework.util.StringUtils; /** * Convenience class for creating and removing {@link JobExecution} instances from a @@ -92,7 +79,6 @@ public class JobRepositoryTestUtils { /** * @param jobRepository the jobRepository to set */ - @Autowired public void setJobRepository(JobRepository jobRepository) { this.jobRepository = jobRepository; } diff --git a/spring-batch-test/src/main/java/org/springframework/batch/test/context/BatchTestContextBeanPostProcessor.java b/spring-batch-test/src/main/java/org/springframework/batch/test/context/BatchTestContextBeanPostProcessor.java index 536875504..ca3046f4d 100644 --- a/spring-batch-test/src/main/java/org/springframework/batch/test/context/BatchTestContextBeanPostProcessor.java +++ b/spring-batch-test/src/main/java/org/springframework/batch/test/context/BatchTestContextBeanPostProcessor.java @@ -16,7 +16,10 @@ package org.springframework.batch.test.context; import org.springframework.batch.core.Job; +import org.springframework.batch.core.launch.JobLauncher; +import org.springframework.batch.core.repository.JobRepository; import org.springframework.batch.test.JobLauncherTestUtils; +import org.springframework.batch.test.JobRepositoryTestUtils; import org.springframework.beans.BeansException; import org.springframework.beans.factory.ObjectProvider; import org.springframework.beans.factory.annotation.Autowired; @@ -34,15 +37,34 @@ public class BatchTestContextBeanPostProcessor implements BeanPostProcessor { private ObjectProvider jobProvider; + private ObjectProvider jobRepositoryProvider; + + private ObjectProvider jobLauncherProvider; + @Autowired public void setJobProvider(ObjectProvider jobProvider) { this.jobProvider = jobProvider; } + @Autowired + public void setJobRepositoryProvider(ObjectProvider jobRepositoryProvider) { + this.jobRepositoryProvider = jobRepositoryProvider; + } + + @Autowired + public void setJobLauncherProvider(ObjectProvider jobLauncherProvider) { + this.jobLauncherProvider = jobLauncherProvider; + } + @Override public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException { if (bean instanceof JobLauncherTestUtils jobLauncherTestUtils) { this.jobProvider.ifUnique(jobLauncherTestUtils::setJob); + this.jobRepositoryProvider.ifUnique(jobLauncherTestUtils::setJobRepository); + this.jobLauncherProvider.ifUnique(jobLauncherTestUtils::setJobLauncher); + } + if (bean instanceof JobRepositoryTestUtils jobRepositoryTestUtils) { + this.jobRepositoryProvider.ifUnique(jobRepositoryTestUtils::setJobRepository); } return bean; } diff --git a/spring-batch-test/src/main/java/org/springframework/batch/test/context/SpringBatchTest.java b/spring-batch-test/src/main/java/org/springframework/batch/test/context/SpringBatchTest.java index 51cfb1c2f..570884db1 100644 --- a/spring-batch-test/src/main/java/org/springframework/batch/test/context/SpringBatchTest.java +++ b/spring-batch-test/src/main/java/org/springframework/batch/test/context/SpringBatchTest.java @@ -35,18 +35,16 @@ import org.springframework.test.context.junit.jupiter.SpringExtension; * Annotation that can be specified on a test class that runs Spring Batch based tests. * Provides the following features over the regular Spring TestContext Framework: *
    - *
  • Registers a {@link JobLauncherTestUtils} bean with the - * {@link BatchTestContextCustomizer#JOB_LAUNCHER_TEST_UTILS_BEAN_NAME} which can be used - * in tests for launching jobs and steps.
  • - *
  • Registers a {@link JobRepositoryTestUtils} bean with the - * {@link BatchTestContextCustomizer#JOB_REPOSITORY_TEST_UTILS_BEAN_NAME} which can be - * used in tests setup to create or remove job executions.
  • + *
  • Registers a {@link JobLauncherTestUtils} bean named "jobLauncherTestUtils" which + * can be used in tests for launching jobs and steps.
  • + *
  • Registers a {@link JobRepositoryTestUtils} bean named "jobRepositoryTestUtils" + * which can be used in tests setup to create or remove job executions.
  • *
  • Registers the {@link StepScopeTestExecutionListener} and * {@link JobScopeTestExecutionListener} as test execution listeners which are required to * test step/job scoped beans.
  • *
*

- * A typical usage of this annotation with JUnit 4 is like: + * A typical usage of this annotation with JUnit 4 is like the following: * *

  * @RunWith(SpringRunner.class)
@@ -66,7 +64,7 @@ import org.springframework.test.context.junit.jupiter.SpringExtension;
  *    @Before
  *    public void setup() {
  *       this.jobRepositoryTestUtils.removeJobExecutions();
- *       this.jobLauncherTestUtils.setJob(this.jobUnderTest);
+ *       this.jobLauncherTestUtils.setJob(this.jobUnderTest); // this is optional if the job is unique
  *    }
  *
  *    @Test
@@ -84,9 +82,9 @@ import org.springframework.test.context.junit.jupiter.SpringExtension;
  * }
  * 
* - * For JUnit 5, this annotation can be used without having to manually register the + * For JUnit 5, this annotation can be used without manually registering the * {@link SpringExtension} since {@code @SpringBatchTest} is meta-annotated with - * {@code @ExtendWith(SpringExtension.class)}: + * {@code @ExtendWith(SpringExtension.class)}. Here is an example: * *
  * @SpringBatchTest
@@ -101,7 +99,7 @@ import org.springframework.test.context.junit.jupiter.SpringExtension;
  *
  *    @BeforeEach
  *    public void setup(@Autowired Job jobUnderTest) {
- *       this.jobLauncherTestUtils.setJob(jobUnderTest);
+ *       this.jobLauncherTestUtils.setJob(jobUnderTest); // this is optional if the job is unique
  *       this.jobRepositoryTestUtils.removeJobExecutions();
  *    }
  *
@@ -124,6 +122,12 @@ import org.springframework.test.context.junit.jupiter.SpringExtension;
  * is the job under test, then this annotation will set that job in the
  * {@link JobLauncherTestUtils} automatically.
  *
+ * The test context must contain a JobRepository and a
+ * JobLauncher beans for this annotation to properly set up test utilities.
+ * In the previous example, the imported configuration class
+ * MyBatchJobConfiguration is expected to have such beans defined in it (or
+ * imported from another configuration class). 
+ *
  * @author Mahmoud Ben Hassine
  * @since 4.1
  * @see JobLauncherTestUtils
diff --git a/spring-batch-test/src/test/java/org/springframework/batch/test/JobLauncherTestUtilsTests.java b/spring-batch-test/src/test/java/org/springframework/batch/test/JobLauncherTestUtilsTests.java
index 3a3bb48d2..fb46c44a1 100644
--- a/spring-batch-test/src/test/java/org/springframework/batch/test/JobLauncherTestUtilsTests.java
+++ b/spring-batch-test/src/test/java/org/springframework/batch/test/JobLauncherTestUtilsTests.java
@@ -25,12 +25,12 @@ import org.springframework.batch.core.Step;
 import org.springframework.batch.core.StepContribution;
 import org.springframework.batch.core.configuration.annotation.EnableBatchProcessing;
 import org.springframework.batch.core.job.builder.JobBuilder;
+import org.springframework.batch.core.launch.JobLauncher;
 import org.springframework.batch.core.repository.JobRepository;
 import org.springframework.batch.core.scope.context.ChunkContext;
 import org.springframework.batch.core.step.builder.StepBuilder;
 import org.springframework.batch.core.step.tasklet.Tasklet;
 import org.springframework.batch.repeat.RepeatStatus;
-import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.context.ApplicationContext;
 import org.springframework.context.annotation.AnnotationConfigApplicationContext;
 import org.springframework.context.annotation.Bean;
@@ -97,9 +97,11 @@ class JobLauncherTestUtilsTests {
 		}
 
 		@Bean
-		public JobLauncherTestUtils testUtils(Job jobUnderTest) {
+		public JobLauncherTestUtils testUtils(Job jobUnderTest, JobRepository jobRepository, JobLauncher jobLauncher) {
 			JobLauncherTestUtils jobLauncherTestUtils = new JobLauncherTestUtils();
 			jobLauncherTestUtils.setJob(jobUnderTest);
+			jobLauncherTestUtils.setJobRepository(jobRepository);
+			jobLauncherTestUtils.setJobLauncher(jobLauncher);
 
 			return jobLauncherTestUtils;
 		}
diff --git a/spring-batch-test/src/test/java/org/springframework/batch/test/StepScopeAnnotatedListenerIntegrationTests.java b/spring-batch-test/src/test/java/org/springframework/batch/test/StepScopeAnnotatedListenerIntegrationTests.java
index 7b548a4f5..e26410dcb 100644
--- a/spring-batch-test/src/test/java/org/springframework/batch/test/StepScopeAnnotatedListenerIntegrationTests.java
+++ b/spring-batch-test/src/test/java/org/springframework/batch/test/StepScopeAnnotatedListenerIntegrationTests.java
@@ -15,14 +15,13 @@
  */
 package org.springframework.batch.test;
 
-import static org.junit.jupiter.api.Assertions.assertEquals;
-
 import java.util.ArrayList;
 import java.util.List;
 
 import javax.sql.DataSource;
 
 import org.junit.jupiter.api.Test;
+
 import org.springframework.batch.core.ExitStatus;
 import org.springframework.batch.core.Job;
 import org.springframework.batch.core.JobExecution;
@@ -33,6 +32,7 @@ import org.springframework.batch.core.annotation.BeforeStep;
 import org.springframework.batch.core.configuration.annotation.EnableBatchProcessing;
 import org.springframework.batch.core.configuration.annotation.StepScope;
 import org.springframework.batch.core.job.builder.JobBuilder;
+import org.springframework.batch.core.launch.JobLauncher;
 import org.springframework.batch.core.repository.JobRepository;
 import org.springframework.batch.core.step.builder.StepBuilder;
 import org.springframework.batch.item.Chunk;
@@ -49,6 +49,8 @@ import org.springframework.lang.Nullable;
 import org.springframework.test.context.junit.jupiter.SpringJUnitConfig;
 import org.springframework.transaction.PlatformTransactionManager;
 
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
 @SpringJUnitConfig
 class StepScopeAnnotatedListenerIntegrationTests {
 
@@ -104,8 +106,11 @@ class StepScopeAnnotatedListenerIntegrationTests {
 		private PlatformTransactionManager transactionManager;
 
 		@Bean
-		JobLauncherTestUtils jobLauncherTestUtils() {
-			return new JobLauncherTestUtils();
+		JobLauncherTestUtils jobLauncherTestUtils(JobRepository jobRepository, JobLauncher jobLauncher) {
+			JobLauncherTestUtils jobLauncherTestUtils = new JobLauncherTestUtils();
+			jobLauncherTestUtils.setJobRepository(jobRepository);
+			jobLauncherTestUtils.setJobLauncher(jobLauncher);
+			return jobLauncherTestUtils;
 		}
 
 		@Bean
diff --git a/spring-batch-test/src/test/resources/job-runner-context.xml b/spring-batch-test/src/test/resources/job-runner-context.xml
index 5751979ee..96fa9648e 100644
--- a/spring-batch-test/src/test/resources/job-runner-context.xml
+++ b/spring-batch-test/src/test/resources/job-runner-context.xml
@@ -4,7 +4,9 @@
 	xsi:schemaLocation="http://www.springframework.org/schema/beans https://www.springframework.org/schema/beans/spring-beans.xsd
 		http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd">
 
-	
-	
+	
+		
+		
+