-
Notifications
You must be signed in to change notification settings - Fork 2.4k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Multiple Job unit testing with @SpringBatchTest #3699
Comments
The utility in question |
So I might chime in here. I'm pretty good at spring and setting up integration tests, and setting up spring batch tests has been quite the nightmare. I have a spring boot web application that is also enabled for spring batch. A few issues I've run into:
So I guess from where I'm sitting, I'm wondering why force the developer to wire only one bean by creating custom spring boot applications for each test when Spring Integration Tests are designed to re-use the context? Also, what would the Configuration Class for So I think the intention here was to make testing easy, and its likely simple to use for simple applications or proof of concepts, but I find myself tearing my hair out trying to get anything to work right in a real world application. I'll try out your Thanks! There is a lot there but hopefully it might be helpful feedback to have about trying to get anything working around these use cases. |
@jblayneyXpanxion
|
@manumouton thanks! It helps to get any feedback on this. I've tried this intermittently trying to get things going, and I have steps created with the @StepScope so that they can use JobParameters on construction, and this setup works and even autowires the jobLauncher and jobRepository into the jobLauncherTestUtils which is great. So thanks! Another thing that doesn't seem to be documented very well in any spring tutorials is the use of:
This seems to asynchronously launch the job -> It won't run it and return the finished execution as the examples seem to imply. Running the test straight through references the jobExecution which hasn't run yet or hasn't completed, and I'll often get a stack trace in the output which has this error: However when I debug the test, I can see the full job execution output on the console and I don't see this error, so I believe that debugging line by line gives the job time to complete before all of the assertions are run. The only thing I can think to do for this is to run a loop waiting for completion of the job with some sleep statements, which isn't ideal. It seems odd that spring's examples and tutorials would show immediate assertions on the jobExecution right after launch if this causes a race condition. Would also be nice to see a helper method in jobLauncherTestUtils to wait for a job's execution to complete. Thanks again, and any additional feedback would be welcome. |
👍 you're welcome.
Unfortunately, this is also the only way I can see right now.
I totally agree! Thanks @jblayneyXpanxion |
Guys, there's always a way to leave single |
The same behaviour happens if multiple datasources are defined (which is a common case) since
Based on what Michael said, I will update the documentation to explicitly mention that the test context is expected to have a single autowire candidate for the job (and datasource). Removing That said, I believe the root cause of the issue is importing an application context with multiple jobs in the same test class (ie trying to test multiple jobs in the same test class). Following the unix philosophy of making one thing do one thing and do it well, I would define each job in its own configuration class, something like: @EnableBatchProcessing
class BaseJobConfiguration {
// common job infrastructure beans (datasource, job repository, etc)
}
@Configuration
class Job1Configuration extends BaseJobConfiguration {
// beans needed by job1
@Bean
public Job job1() {};
}
@Configuration
class Job2Configuration extends BaseJobConfiguration {
// beans needed by job2
@Bean
public Job job2() {};
} and test each job in its own test class as well: @RunWith(SpringRunner.class)
@SpringBatchTest
@ContextConfiguration(classes = {Job1Configuration.class})
public class Job1Tests {
@Autowired
private JobLauncherTestUtils jobLauncherTestUtils;
@Test
public void testSunnyDay() {}
@Test
public void testFailureCase() {}
// other tests for job1
}
// same for Job2Tests I think it's a good practice to isolate job definitions and their corresponding tests, which solves the issue by design. The fact that
The example in the Javadoc of
|
May be late but i made this example to demonstrate "Multiple Job unit testing with @SpringBatchTest @SpringBootTest and Modular configuration" https://github.com/desprez/springbatch-modular I think this case may be more common than you think and hope it can help others |
Hope this helps someone ^^; Abstract class for test
JUnit Test
|
Hi all,
From documentation, it seems impossible to unit test a Spring Batch with more than one job, problem is JobLauncherTestUtils autowiring the Job. This can be resolved as in #1237 but, as docs state to use @SpringBatchTest (#889), a default JobLauncherTestUtils bean is created in BatchTestContextCustomizer so, even if you don't use any JobLauncherTestUtils at all, it tries to create one and fails on no single Job bean.
Not sure if this has a simple resolution, may be deleting autowired Job in JobLauncherTestUtils, or allowing some kind of @SpringBatchTest customization, but I think that it could be, at least, mentioned in unit testing docs, so to not use @SpringBatchTest annotation if you have more than one Job bean.
The text was updated successfully, but these errors were encountered: