3

I have a launch-context.xml that defines 7 different jobs, all of which have the same parent. They have names like "jobA", "jobB" and so on.

I tried:

 @RunWith(SpringJUnit4ClassRunner.class)
 @ContextConfiguration(locations = { "/launch-context.xml", "/OurBatchKernelTestConfig.xml" })
 public class AllTest extends BaseRaptorBatchTest {

     @Autowired
     private JobLauncherTestUtils utils;

     @Autowired
     @Qualifier(value="jobA")
     private Job job;

     @Test
     public void testLaunch() {
         Properties p = new Properties(); // then I set these up.
         JobExecution je = utils.launchJob(paraCvter.getJobParameters(p));
     }
 }

This does not work.

I get an exception like:

 STDOUT [WARN ] [2015.04.15 11:14:42] support.GenericApplicationContext - Exception encountered during context initialization - cancelling refresh attempt
  org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'jobLauncherTestUtilsForSnapshot': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire method: public void org.springframework.batch.test.JobLauncherTestUtils.setJob(org.springframework.batch.core.Job); nested exception is org.springframework.beans.factory.NoUniqueBeanDefinitionException: No qualifying bean of type [org.springframework.batch.core.Job] is defined: expected single matching bean but found 2: coverageRuleBatch,generateMetricsSnapshotJob

I also tried:

https://stackoverflow.com/a/29658577/869809

and I tried:

https://stackoverflow.com/a/36352437/869809

Neither of these work.

I can create a copy of my launch-content.xml and remove the other jobs. Then I refer to that in the annotation and all is good. But I then need 7 different xml files. Ick.

Community
  • 1
  • 1
Ray Kiddy
  • 3,521
  • 3
  • 25
  • 32

2 Answers2

1

Based on the information in the exception's message, it appears that you need to disambiguate what bean in your Spring context should be autowired to the member variable utils. Something like this:

 @Autowired
 @Qualifier(value="coverageRuleBatch")
 private JobLauncherTestUtils utils;

or this:

 @Autowired
 @Qualifier(value="generateMetricsSnapshotJob")
 private JobLauncherTestUtils utils;

should resolve the ambiguity.

StvnBrkdll
  • 3,924
  • 1
  • 24
  • 31
  • So, first I wanted to use an auto-wired JobLauncherTestUtils instance and call setJob on it with the job desired. But auto-wiring the job ivar using the @Qualifier(value="jobA") did not work. – Ray Kiddy Nov 17 '16 at 21:27
  • Second, I tried using a sub-class of JobLauncherTestUtils that included the set of my job. That did not work either. – Ray Kiddy Nov 17 '16 at 21:28
  • Actually you are suggesting the same solution as the one in http://stackoverflow.com/a/36352437/869809, which I cited above. That did not work. – Ray Kiddy Nov 17 '16 at 21:29
  • If autowiring is not working you might try constructor injection. Although I have had good success with autowire +qualifier – StvnBrkdll Nov 17 '16 at 21:33
0

Obviously your test config shouldn't instantiate more than 1 Job as JobLauncherTestUtils expect only one bean.

In order to workaround JobLauncherTestUtils limitations you can manage dependencies for it yourselves via constructor/setters as done in: Spring Batch JUnit test for multiple jobs

Alternatively you can subclass JobLauncherTestUtils and set @Qualifier on:

@Autowired
@Qualifier("myChosenJobBeanName")
public void setJob(Job job) {
    this.job = job;
}

but you need to override it for each job you like to test. It is better to end with factory method.

You can launch job without JobLauncherTestUtils. Just study implementation. It is simple as:

getJobLauncher().run(this.job, jobParameters);

Also look to How can I qualify an autowired setter that I don't "own"

gavenkoa
  • 45,285
  • 19
  • 251
  • 303