не может загрузить контекст приложения из junit для весеннего пакетного задания

html, body
{
  height: 100%;
  margin: 0;
  padding: 0;
}
0
задан Mia 8 March 2019 в 18:51
поделиться

1 ответ

Моя цель - уметь тестировать отдельные шаги.

Вы можете использовать JobLauncherTestUtils#launchStep(String stepName) для запуска определенного шага, а не всей работы. Если вы хотите выполнить модульное тестирование определенного шага, я бы порекомендовал импортировать только конфигурацию, необходимую для тестирования шага (я имею в виду RestTemplateConfig, SftpConfig и т. Д., Если этот шаг действительно не нужен).

Обратите внимание, что тестируемое задание должно быть объявлено как bean-компонент в контексте теста, потому что оно автоматически подключено в JobLauncherTestUtils. В вашем случае я предполагаю, что он определен в классе BatchProcessingConfiguration.

Типичный пошаговый тест будет выглядеть примерно так:

import org.junit.Assert;
import org.junit.Test;
import org.junit.runner.RunWith;

import org.springframework.batch.core.ExitStatus;
import org.springframework.batch.core.JobExecution;
import org.springframework.batch.core.JobParameters;
import org.springframework.batch.test.JobLauncherTestUtils;
import org.springframework.batch.test.context.SpringBatchTest;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringRunner;

@RunWith(SpringRunner.class)
@SpringBatchTest
@ContextConfiguration(classes = {JobConfiguration.class}) // contains the job/step definition
public class JobTest {

   @Autowired
   private JobLauncherTestUtils jobLauncherTestUtils;

   @Test
   public void testStep() throws Exception {
      // given
      JobParameters jobParameters = jobLauncherTestUtils.getUniqueJobParameters();

      // when
      JobExecution jobExecution = jobLauncherTestUtils.launchStep("myStep", jobParameters);

      // then
      Assert.assertEquals(ExitStatus.COMPLETED, jobExecution.getExitStatus());
   }

}

Примечание: SpringBatchTest было добавлено в v4.1.

РЕДАКТИРОВАТЬ для дополнительных комментариев: Когда контекст приложения содержит несколько рабочих компонентов, невозможно узнать, какой из них внедрить в JobLauncherTestUtils. В этом случае JobLauncherTestUtils следует создать вручную и настроить с помощью тестируемого задания. Вот пример:

import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;

import org.springframework.batch.core.ExitStatus;
import org.springframework.batch.core.Job;
import org.springframework.batch.core.JobExecution;
import org.springframework.batch.core.JobParametersIncrementer;
import org.springframework.batch.core.JobParametersValidator;
import org.springframework.batch.core.configuration.annotation.EnableBatchProcessing;
import org.springframework.batch.core.job.DefaultJobParametersValidator;
import org.springframework.batch.core.launch.JobLauncher;
import org.springframework.batch.core.repository.JobRepository;
import org.springframework.batch.test.JobLauncherTestUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.lang.Nullable;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringRunner;

/*
 * This test class shows how to use the JobLauncherTestUtils when the application
 * context contains multiple jobs. Since the job is autowired in JobLauncherTestUtils (see setter),
 * it is not possible to autowire one job (ambiguous injection). Hence, it is required to either:
 *  - Not autowire the JobLauncherTestUtils (as shown in this class)
 *  - Or separate job definitions and use a test class for each job (better solution IMO, each job has its own test)
 */
@RunWith(SpringRunner.class)
@ContextConfiguration(classes = TestMultipleJobsWithJobLauncherTestUtils.JobsConfiguration.class)
public class TestMultipleJobsWithJobLauncherTestUtils {

    // don't autowire the JobLauncherTestUtils in this case otherwise No qualifying bean of type 'org.springframework.batch.core.Job' available: expected single matching bean but found 2: job1,job2
    private JobLauncherTestUtils jobLauncherTestUtils = new JobLauncherTestUtils();

    @Autowired
    private Job job1;

    @Autowired
    private Job job2;

    @Autowired
    private JobLauncher jobLauncher;
    @Autowired
    private JobRepository jobRepository;

    @Before
    public void setUp() {
        jobLauncherTestUtils.setJobLauncher(jobLauncher);
        jobLauncherTestUtils.setJobRepository(jobRepository);
    }

    @Test
    public void testJob1() throws Exception {
        // given
        jobLauncherTestUtils.setJob(job1);

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

        // then
        Assert.assertEquals(ExitStatus.COMPLETED, jobExecution.getExitStatus());
    }

    @Test
    public void testJob2() throws Exception {
        // given
        jobLauncherTestUtils.setJob(job2);

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

        // then
        Assert.assertEquals(ExitStatus.COMPLETED, jobExecution.getExitStatus());
    }

    @Configuration
    @EnableBatchProcessing
    public static class JobsConfiguration {

        @Bean
        public Job job1() {
            return new SimpleJob("job1");
        }

        @Bean
        public Job job2() {
            return new SimpleJob("job2");
        }

        // Don't declare the JobLauncherTestUtils as a bean to avoid dependecy injection
//      @Bean
//      public JobLauncherTestUtils jobLauncherTestUtils() {
//          return new JobLauncherTestUtils();
//      }

    }

    static class SimpleJob implements Job {

        private String name;

        public SimpleJob(String name) {
            this.name = name;
        }

        @Override
        public String getName() {
            return name;
        }

        @Override
        public boolean isRestartable() {
            return false;
        }

        @Override
        public void execute(JobExecution execution) {
            System.out.println("Executing job " + this.name);
            execution.setExitStatus(ExitStatus.COMPLETED);
        }

        @Nullable
        @Override
        public JobParametersIncrementer getJobParametersIncrementer() {
            return null;
        }

        @Override
        public JobParametersValidator getJobParametersValidator() {
            return new DefaultJobParametersValidator();
        }

    }
}

Надеюсь, это поможет.

0
ответ дан Mahmoud Ben Hassine 8 March 2019 в 18:51
поделиться
Другие вопросы по тегам:

Похожие вопросы: