Golden Recursion Inc. logoGolden Recursion Inc. logo
Advanced Search
User profile

Oksana Shumei

TNEU
Joined January 2022
ContributionsFavoritesActivity
Spring AMQP
had a suggestion from Golden's AI approved byOksana ShumeiOksana Shumei
"Approved suggestion #1322378 from source: https://spring.io/projects/spring-amqp"
February 9, 2022 1:52 pm
Infobox
Spring AMQP
was edited byOksana ShumeiOksana Shumei
February 9, 2022 1:51 pm

Spring AMQP

The Spring AMQP project applies core Spring concepts to the development of AMQP-based messaging solutions. It provides a "template" as a high-level abstraction for sending and receiving messages. It also provides support for Message-driven POJOs with a "listener container".

Spring AMQP
was created byOksana ShumeiOksana Shumei
"Created via: Web app"
February 9, 2022 1:51 pm

Spring AMQP

The Spring AMQP project applies core Spring concepts to the development of AMQP-based messaging solutions. It provides a "template" as a high-level abstraction for sending and receiving messages. It also provides support for Message-driven POJOs with a "listener container".

Spring BatchSpring Batch was edited byOksana ShumeiOksana Shumei
February 9, 2022 1:50 pm
Article  (+380 characters)
@Test
public void filterId() throws Exception {
    final Customer customer = new Customer();
    customer.setId(1);
    customer.setName("name");
    customer.setBirthday(new GregorianCalendar());
    final int id = StepScopeTestUtils.doInStepScope(
        getStepExecution(),
        () -> processor.process(customer).getId()
    );
    Assert.assertEquals(1, id);
}
Spring BatchSpring Batch was edited byOksana ShumeiOksana Shumei
February 9, 2022 1:50 pm
Article  (+295 characters)

Another approach is based on the StepScopeTestUtils utility class. This class is used to create and manipulate StepScope in unit tests in a more flexible way without using dependency injection. For example, reading the ID of the customer filtered by the processor above could be done as follows:

Spring BatchSpring Batch was edited byOksana ShumeiOksana Shumei
February 9, 2022 1:49 pm
Article  (+599 characters)

There are two TestExecutionListeners. One is from the regular Spring Test framework and handles dependency injection from the configured application context. The other is the Spring Batch StepScopeTestExecutionListener that sets up step-scope context for dependency injection into unit tests. A StepContext is created for the duration of a test method and made available to any dependencies that are injected. The default behavior is just to create a StepExecution with fixed properties. Alternatively, the StepContext can be provided by the test case as a factory method returning the correct type.

Spring BatchSpring Batch was edited byOksana ShumeiOksana Shumei
February 9, 2022 1:49 pm
Article  (+759 characters)
@RunWith(SpringRunner.class)
@TestExecutionListeners({DependencyInjectionTestExecutionListener.class, StepScopeTestExecutionListener.class})
@ContextConfiguration(classes = {BatchApplication.class, BatchTestConfiguration.class})
public class BirthdayFilterProcessorTest {

    @Autowired
    private BirthdayFilterProcessor processor;

    public StepExecution getStepExecution() {
        return MetaDataInstanceFactory.createStepExecution();
    }

    @Test
    public void filter() throws Exception {
        final Customer customer = new Customer();
        customer.setId(1);
        customer.setName("name");
        customer.setBirthday(new GregorianCalendar());
        Assert.assertNotNull(processor.process(customer));
    }

}
Spring BatchSpring Batch was edited byOksana ShumeiOksana Shumei
February 9, 2022 1:49 pm
Article  (+144 characters)

The TestExecutionListeners are declared at the class level, and its job is to create a step execution context for each test method. For example:

Spring BatchSpring Batch was edited byOksana ShumeiOksana Shumei
February 9, 2022 1:49 pm
Article  (+758 characters)

Spring Batch introduces additional scopes for step and job contexts. Objects in these scopes use the Spring container as an object factory, so there is only one instance of each such bean per execution step or job. In addition, support is provided for late binding of references accessible from the StepContext or JobContext. The components that are configured at runtime to be step- or job-scoped are tricky to test as standalone components unless you have a way to set the context as if they were in a step or job execution. That is the goal of the org.springframework.batch.test.StepScopeTestExecutionListener and org.springframework.batch.test.StepScopeTestUtils components in Spring Batch, as well as JobScopeTestExecutionListener and JobScopeTestUtils.

Spring BatchSpring Batch was edited byOksana ShumeiOksana Shumei
February 9, 2022 1:48 pm
Article  (+767 characters)
@RunWith(SpringRunner.class)
@ContextConfiguration(classes = {BatchApplication.class, BatchTestConfiguration.class})
public class CustomerReportJobConfigTest {

    @Autowired
    private JobLauncherTestUtils testUtils;

    @Autowired
    private CustomerReportJobConfig config;

    @Test
    public void testEntireJob() throws Exception {
        final JobExecution result = testUtils.getJobLauncher().run(config.customerReportJob(), testUtils.getUniqueJobParameters());
        Assert.assertNotNull(result);
        Assert.assertEquals(BatchStatus.COMPLETED, result.getStatus());
    }

    @Test
    public void testSpecificStep() {
        Assert.assertEquals(BatchStatus.COMPLETED, testUtils.launchStep("taskletStep").getStatus());
    }
}
Spring BatchSpring Batch was edited byOksana ShumeiOksana Shumei
February 9, 2022 1:48 pm
Article  (+98 characters)

A typical test for a job and a step looks as follows (and can use any mocking frameworks as well):

Spring BatchSpring Batch was edited byOksana ShumeiOksana Shumei
February 9, 2022 1:48 pm
Article  (+176 characters)
@Configuration
public class BatchTestConfiguration {
    @Bean
    public JobLauncherTestUtils jobLauncherTestUtils() {
        return new JobLauncherTestUtils();
    }
}
Spring BatchSpring Batch was edited byOksana ShumeiOksana Shumei
February 9, 2022 1:48 pm
Article  (+290 characters)

There is a utility class org.springframework.batch.test.JobLauncherTestUtils to test batch jobs. It provides methods for launching an entire job as well as allowing for end-to-end testing of individual steps without having to run every step in the job. It must be declared as a Spring bean:

Spring BatchSpring Batch was edited byOksana ShumeiOksana Shumei
February 9, 2022 1:48 pm
Article  (+68 characters)
@RunWith(SpringRunner.class)
@ContextConfiguration(classes = {...})

Spring BatchSpring Batch was edited byOksana ShumeiOksana Shumei
February 9, 2022 1:47 pm
Article  (+159 characters)

Usually, to run unit tests in a Spring Boot application, the framework must load a corresponding ApplicationContext. Two annotations are used for this purpose:

Spring BatchSpring Batch was edited byOksana ShumeiOksana Shumei
February 9, 2022 1:47 pm
Article  (+25 characters)

Spring Batch Unit Testing

Spring BatchSpring Batch was edited byOksana ShumeiOksana Shumei
February 9, 2022 1:47 pm
Article  (+406 characters)
@Autowired
private JobOperator operator;
 
@Autowired
private JobExplorer jobs;
 
@Scheduled(fixedRate = 5000)
public void run() throws Exception {
    List<JobInstance> lastInstances = jobs.getJobInstances(JOB_NAME, 0, 1);
    if (lastInstances.isEmpty()) {
        jobLauncher.run(customerReportJob(), new JobParameters());
    } else {
        operator.startNextInstance(JOB_NAME);
    }
}
Spring BatchSpring Batch was edited byOksana ShumeiOksana Shumei
February 9, 2022 1:47 pm
Article  (+189 characters)

Alternatively, you can launch the next job in a sequence of JobInstances determined by the JobParametersIncrementer attached to the specified job with SimpleJobOperator.startNextInstance():

Spring BatchSpring Batch was edited byOksana ShumeiOksana Shumei
February 9, 2022 1:46 pm
Article  (+224 characters)
@Scheduled(fixedRate = 5000)
public void run() throws Exception {
    jobLauncher.run(
        customerReportJob(),
        new JobParametersBuilder().addLong("uniqueness", System.nanoTime()).toJobParameters()
    );
}
Spring BatchSpring Batch was edited byOksana ShumeiOksana Shumei
February 9, 2022 1:46 pm
Article  (+188 characters)

There are two ways of avoiding this problem when you schedule a batch job.

One is to be sure to introduce one or more unique parameters (e.g., actual start time in nanoseconds) to each job:

Golden logo