Skip to content
Closed
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Next Next commit
Add flag to @SpringBatchTest to autowire a job bean
  • Loading branch information
hpoettker committed Oct 23, 2022
commit b2bf826b2c5210d4ef9162b76391ac0d9bf04289
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2018-2021 the original author or authors.
* Copyright 2018-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.
Expand All @@ -15,9 +15,13 @@
*/
package org.springframework.batch.test.context;

import java.util.Objects;

import org.springframework.batch.test.JobLauncherTestUtils;
import org.springframework.batch.test.JobRepositoryTestUtils;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.beans.factory.support.RootBeanDefinition;
import org.springframework.context.ConfigurableApplicationContext;
Expand All @@ -39,27 +43,47 @@ public class BatchTestContextCustomizer implements ContextCustomizer {

private static final String JOB_REPOSITORY_TEST_UTILS_BEAN_NAME = "jobRepositoryTestUtils";

private final boolean autowireJob;

public BatchTestContextCustomizer(boolean autowireJob) {
this.autowireJob = autowireJob;
}

@Override
public void customizeContext(ConfigurableApplicationContext context, MergedContextConfiguration mergedConfig) {
ConfigurableListableBeanFactory beanFactory = context.getBeanFactory();
Assert.isInstanceOf(BeanDefinitionRegistry.class, beanFactory,
"The bean factory must be an instance of BeanDefinitionRegistry");
BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory;

registry.registerBeanDefinition(JOB_LAUNCHER_TEST_UTILS_BEAN_NAME,
new RootBeanDefinition(JobLauncherTestUtils.class));
registry.registerBeanDefinition(JOB_LAUNCHER_TEST_UTILS_BEAN_NAME, buildJobLauncherTestUtilsBeanDefinition());
registry.registerBeanDefinition(JOB_REPOSITORY_TEST_UTILS_BEAN_NAME,
new RootBeanDefinition(JobRepositoryTestUtils.class));
}

private BeanDefinition buildJobLauncherTestUtilsBeanDefinition() {
var beanDefinitionBuilder = BeanDefinitionBuilder.genericBeanDefinition(JobLauncherTestUtils.class);
if (this.autowireJob) {
beanDefinitionBuilder.addAutowiredProperty("job");
}
return beanDefinitionBuilder.getBeanDefinition();
}

@Override
public boolean equals(Object obj) {
return obj != null && getClass() == obj.getClass();
if (this == obj) {
return true;
}
if (obj == null || getClass() != obj.getClass()) {
return false;
}
BatchTestContextCustomizer that = (BatchTestContextCustomizer) obj;
return this.autowireJob == that.autowireJob;
}

@Override
public int hashCode() {
return getClass().hashCode();
return Objects.hash(this.autowireJob);
}

}
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2018 the original author or authors.
* Copyright 2018-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.
Expand Down Expand Up @@ -33,8 +33,10 @@ public class BatchTestContextCustomizerFactory implements ContextCustomizerFacto
@Override
public ContextCustomizer createContextCustomizer(Class<?> testClass,
List<ContextConfigurationAttributes> configAttributes) {
if (AnnotatedElementUtils.hasAnnotation(testClass, SpringBatchTest.class)) {
return new BatchTestContextCustomizer();
var annotationAttributes = AnnotatedElementUtils.findMergedAnnotationAttributes(testClass,
SpringBatchTest.class, false, false);
if (annotationAttributes != null) {
return new BatchTestContextCustomizer(annotationAttributes.getBoolean("autowireJob"));
}
return null;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,14 @@

import org.junit.jupiter.api.extension.ExtendWith;

import org.springframework.batch.core.Job;
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.beans.factory.NoSuchBeanDefinitionException;
import org.springframework.beans.factory.NoUniqueBeanDefinitionException;
import org.springframework.context.annotation.Primary;
import org.springframework.test.context.TestExecutionListeners;
import org.springframework.test.context.junit.jupiter.SpringExtension;

Expand Down Expand Up @@ -136,4 +140,15 @@
@ExtendWith(SpringExtension.class)
public @interface SpringBatchTest {

/**
* Indicate whether a {@link Job} bean shall be autowired into the registered
* {@link JobLauncherTestUtils} bean. If set to true, and no {@link Job} bean exists,
* then a {@link NoSuchBeanDefinitionException} will be thrown. If set to true, and
* multiple {@link Job} beans exists but none has the name {@literal job} or is marked
* with {@link Primary}, then a {@link NoUniqueBeanDefinitionException} will be
* thrown.
* @return if a {@link Job} shall be autowired. Defaults to {@code false}.
*/
boolean autowireJob() default false;

}
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@
* @author Mahmoud Ben Hassine
*/
@RunWith(SpringRunner.class)
@SpringBatchTest
@SpringBatchTest(autowireJob = true)
@ContextConfiguration
public class SpringBatchTestJUnit4Tests {

Expand All @@ -69,9 +69,6 @@ public class SpringBatchTestJUnit4Tests {
@Autowired
private ItemReader<String> jobScopedItemReader;

@Autowired
private Job jobUnderTest;

@Before
public void setUp() {
this.jobRepositoryTestUtils.removeJobExecutions();
Expand Down Expand Up @@ -105,9 +102,6 @@ public void testJobScopedItemReader() throws Exception {

@Test
public void testJob() throws Exception {
// given
this.jobLauncherTestUtils.setJob(this.jobUnderTest);

// when
JobExecution jobExecution = this.jobLauncherTestUtils.launchJob();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@

import javax.sql.DataSource;

import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;

Expand Down Expand Up @@ -55,7 +54,7 @@
*
* @author Mahmoud Ben Hassine
*/
@SpringBatchTest
@SpringBatchTest(autowireJob = true)
@SpringJUnitConfig
public class SpringBatchTestJUnit5Tests {

Expand All @@ -72,8 +71,7 @@ public class SpringBatchTestJUnit5Tests {
private ItemReader<String> jobScopedItemReader;

@BeforeEach
void setup(@Autowired Job jobUnderTest) {
this.jobLauncherTestUtils.setJob(jobUnderTest);
void setup() {
this.jobRepositoryTestUtils.removeJobExecutions();
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,15 +15,15 @@
*/
package org.springframework.batch.test.context;

import java.util.Collections;
import java.util.List;

import org.junit.jupiter.api.Test;

import org.springframework.test.context.ContextConfigurationAttributes;
import org.springframework.test.context.ContextCustomizer;

import static org.junit.jupiter.api.Assertions.assertNotNull;
import static java.util.Collections.emptyList;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNull;

/**
Expand All @@ -37,20 +37,33 @@ class BatchTestContextCustomizerFactoryTests {
void testCreateContextCustomizer_whenAnnotationIsPresent() {
// given
Class<MyJobTest> testClass = MyJobTest.class;
List<ContextConfigurationAttributes> configAttributes = Collections.emptyList();
List<ContextConfigurationAttributes> configAttributes = emptyList();

// when
ContextCustomizer contextCustomizer = this.factory.createContextCustomizer(testClass, configAttributes);

// then
assertNotNull(contextCustomizer);
assertEquals(new BatchTestContextCustomizer(false), contextCustomizer);
}

@Test
void testCreateContextCustomizer_whenAnnotationIsPresentAndFlagSet() {
// given
Class<MyUniqueJobTest> testClass = MyUniqueJobTest.class;
List<ContextConfigurationAttributes> configAttributes = emptyList();

// when
ContextCustomizer contextCustomizer = this.factory.createContextCustomizer(testClass, configAttributes);

// then
assertEquals(new BatchTestContextCustomizer(true), contextCustomizer);
}

@Test
void testCreateContextCustomizer_whenAnnotationIsAbsent() {
// given
Class<MyOtherJobTest> testClass = MyOtherJobTest.class;
List<ContextConfigurationAttributes> configAttributes = Collections.emptyList();
List<ContextConfigurationAttributes> configAttributes = emptyList();

// when
ContextCustomizer contextCustomizer = this.factory.createContextCustomizer(testClass, configAttributes);
Expand All @@ -64,6 +77,11 @@ private static class MyJobTest {

}

@SpringBatchTest(autowireJob = true)
private static class MyUniqueJobTest {

}

private static class MyOtherJobTest {

}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@
package org.springframework.batch.test.context;

import org.junit.jupiter.api.Test;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.ValueSource;
import org.mockito.Mockito;

import org.springframework.context.ConfigurableApplicationContext;
Expand All @@ -24,6 +26,8 @@

import static org.hamcrest.CoreMatchers.containsString;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNotEquals;
import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.junit.jupiter.api.Assertions.assertTrue;

Expand All @@ -32,35 +36,52 @@
*/
class BatchTestContextCustomizerTests {

private final BatchTestContextCustomizer contextCustomizer = new BatchTestContextCustomizer();

@Test
void testCustomizeContext() {
@ParameterizedTest
@ValueSource(booleans = { true, false })
void testCustomizeContext(boolean autowireJob) {
// given
ConfigurableApplicationContext context = new GenericApplicationContext();
BatchTestContextCustomizer contextCustomizer = new BatchTestContextCustomizer(autowireJob);
GenericApplicationContext context = new GenericApplicationContext();
MergedContextConfiguration mergedConfig = Mockito.mock(MergedContextConfiguration.class);

// when
this.contextCustomizer.customizeContext(context, mergedConfig);
contextCustomizer.customizeContext(context, mergedConfig);

// then
assertTrue(context.containsBean("jobLauncherTestUtils"));
assertTrue(context.containsBean("jobRepositoryTestUtils"));

var beanDefinition = context.getBeanDefinition("jobLauncherTestUtils");
assertEquals(autowireJob, beanDefinition.getPropertyValues().contains("job"));
}

@Test
void testCustomizeContext_whenBeanFactoryIsNotAnInstanceOfBeanDefinitionRegistry() {
// given
BatchTestContextCustomizer contextCustomizer = new BatchTestContextCustomizer(false);
ConfigurableApplicationContext context = Mockito.mock(ConfigurableApplicationContext.class);
MergedContextConfiguration mergedConfig = Mockito.mock(MergedContextConfiguration.class);

// when
final Exception expectedException = assertThrows(IllegalArgumentException.class,
() -> this.contextCustomizer.customizeContext(context, mergedConfig));
() -> contextCustomizer.customizeContext(context, mergedConfig));

// then
assertThat(expectedException.getMessage(),
containsString("The bean factory must be an instance of BeanDefinitionRegistry"));
}

@Test
void testEquals() {
assertEquals(new BatchTestContextCustomizer(true), new BatchTestContextCustomizer(true));
assertEquals(new BatchTestContextCustomizer(false), new BatchTestContextCustomizer(false));
assertNotEquals(new BatchTestContextCustomizer(true), new BatchTestContextCustomizer(false));
}

@Test
void testHashCode() {
assertNotEquals(new BatchTestContextCustomizer(true).hashCode(),
new BatchTestContextCustomizer(false).hashCode());
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,8 @@
import io.micrometer.tracing.test.SampleTestRunner;
import org.assertj.core.api.Assertions;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;

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.observability.BatchMetrics;
Expand All @@ -38,7 +36,7 @@

import static io.micrometer.tracing.test.simple.SpansAssert.assertThat;

@SpringBatchTest
@SpringBatchTest(autowireJob = true)
class ObservabilitySampleStepTests extends SampleTestRunner {

@Autowired
Expand All @@ -58,11 +56,6 @@ protected ObservationRegistry createObservationRegistry() {
return BatchMetrics.observationRegistry;
}

@BeforeEach
void setup(@Autowired Job job) {
this.jobLauncherTestUtils.setJob(job);
}

@AfterEach
@Override
protected void closeMeterRegistry() {
Expand Down