Как успешно загрузить класс JobLauncherTestUtils для задачи Spring для теста Spring Batch JUnit 5 - PullRequest
0 голосов
/ 08 апреля 2020

У меня есть эта, казалось бы, простая конфигурация для весеннего теста. Тем не менее, тест не может загрузить контекст. Ошибка говорит мне, что существует неразрешимая циклическая ссылка, связанная с источником данных. Если я удалю источник данных, ошибка изменится на то, что источник данных не был определен. Все, чего я пытаюсь добиться, - это загрузить JobLauncherTestUtils, а затем запустить задание для проверки шагов. Это кажется достаточно простым, но сложно загрузить простую работу для тестирования. Я использую пружинный ботинок 2 на Java 12 и пружину 5 и пакет пружин 2.2.0.RELEASE и JUnit 5 (Юпитер). В чем проблема с настройкой? Какие изменения мне нужно сделать. Я думал, что вам не обязательно указывать конфигурацию источника данных, но он просто не подходит к загрузке без его настройки. Вот моя конфигурация. Я очень признателен за помощь в выяснении того, что не так с моей конфигурацией. Моя цель состоит в том, чтобы просто автоматически подключить класс JobLauncherTestUtils.

like 

class BatchTest {
   @Autowired
   JobLauncherTestUtils jobLauncherTestUtils;
}


import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.springframework.batch.core.Job;
import org.springframework.batch.core.Step;
import org.springframework.batch.core.configuration.annotation.EnableBatchProcessing;
import org.springframework.batch.core.configuration.annotation.JobBuilderFactory;
import org.springframework.batch.core.configuration.annotation.StepBuilderFactory;
import org.springframework.batch.core.launch.JobLauncher;
import org.springframework.batch.core.launch.support.RunIdIncrementer;
import org.springframework.batch.core.launch.support.SimpleJobLauncher;
import org.springframework.batch.core.repository.support.JobRepositoryFactoryBean;
import org.springframework.batch.test.JobLauncherTestUtils;
import org.springframework.batch.test.context.SpringBatchTest;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.batch.BatchAutoConfiguration;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.jdbc.datasource.embedded.EmbeddedDatabase;
import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseBuilder;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.TestPropertySource;
import org.springframework.test.context.junit.jupiter.SpringExtension;


@ExtendWith(SpringExtension.class)
@SpringBatchTest
@ContextConfiguration(classes = {BatchTest.BatchConfiguration.class, 
BatchAutoConfiguration.class})
@TestPropertySource(properties = "debug=true")
public class BatchTest {

@Autowired
private JobLauncherTestUtils jobLauncherTestUtils;

@Test
public void test() {
    this.jobLauncherTestUtils.launchStep("orderProcessingJob");
    //assertions 
}

    @Configuration
    @EnableBatchProcessing
    public static class BatchConfiguration {

    private  JobBuilderFactory jobBuilderFactory;

    @Bean(name="jobLauncherTestUtils")
    public JobLauncherTestUtils jobLauncherTestUtils() throws Exception {
        JobLauncherTestUtils jl = new JobLauncherTestUtils();
        jl.setJobLauncher(jobLauncher());
        jl.setJob(orderProcessorJob());
        jl.setJobRepository(jobRepository().getObject());
        return jl;
    }

        @Bean
        public JobRepositoryFactoryBean jobRepository() {
        JobRepositoryFactoryBean jobRepositoryFactoryBean = new JobRepositoryFactoryBean();
        jobRepositoryFactoryBean.setDataSource(dataSource());
        return jobRepositoryFactoryBean;
      }


    @Bean
    public Job orderProcessorJob() {
        return jobBuilderFactory.get("orderProcessingJob")
                .incrementer(new RunIdIncrementer())
                .flow(orderIntakeStep())
                .end()
                .build();
    }

    private Step orderIntakeStep() {
        // code for order Intake
    }

    @Bean
    public JobLauncher jobLauncher() throws Exception {
        SimpleJobLauncher jobLauncher = new SimpleJobLauncher();
        jobLauncher.setJobRepository(jobRepository().getObject());
        return jobLauncher;
    }


    private  StepBuilderFactory stepBuilderFactory;


    @Bean
    public EmbeddedDatabase dataSource() {
        return new EmbeddedDatabaseBuilder().build();
    }


    @Autowired
    public BatchConfiguration(JobBuilderFactory jobBuilderFactory , 
                                          StepBuilderFactory stepBuilderFactory) {
        this.jobBuilderFactory = jobBuilderFactory;
        this.stepBuilderFactory = stepBuilderFactory;
     }

    }
 }

Вот основной фрагмент трассировки стека, который я вижу:

Причина: org.springframework.beans.factory.UnsatisfiedDependencyException : Ошибка при создании bean-компонента с именем 'batchTest.BatchConfiguration':

Неудовлетворенная зависимость, выраженная через параметр конструктора 0; вложенное исключение

- это org.springframework.beans.factory.UnsatisfiedDependencyException: ошибка при создании bean-компонента с именем org.springframework.batch.core.configuration.annotation.SimpleBatchConfiguration ':

выражено через несоответствие поле «источник данных»; вложенное исключение: org.springframework.beans.factory.BeanCurrentlyInCreationException:

Ошибка создания компонента с именем 'batchTest.BatchConfiguration': запрашиваемый компонент находится в процессе создания: существует неразрешимая циклическая ссылка?

1 Ответ

0 голосов
/ 09 апреля 2020

Неудовлетворенная зависимость, выраженная через поле 'dataSource'; вложенное исключение: org.springframework.beans.factory.BeanCurrentlyInCreationException:

Ошибка создания компонента с именем 'batchTest.BatchConfiguration': запрашиваемый компонент находится в процессе создания: существует неразрешимая циклическая ссылка?

Источник данных, который вы пытаетесь внедрить в BatchConfiguration#jobRepository(), создается в том же классе (метод dataSource()), следовательно, ошибка. Вам нужно извлечь конфигурацию источника данных в отдельный класс, что-то вроде:

@Configuration
public static class DataSourceConfig {
   @Bean
   public EmbeddedDatabase dataSource() {
      return new EmbeddedDatabaseBuilder().build();
   }
}

Затем импортируйте его в ваш BatchConfiguration:

@Configuration
@Import(DataSourceConfig.class)
@EnableBatchProcessing
public static class BatchConfiguration {

   // ..       

   @Bean
   public JobRepositoryFactoryBean jobRepository(DataSource dataSource) {
      JobRepositoryFactoryBean jobRepositoryFactoryBean = new JobRepositoryFactoryBean();
      jobRepositoryFactoryBean.setDataSource(dataSource);
       return jobRepositoryFactoryBean;
  }

  // ..
}

Я бы порекомендовал отделить компоненты инфраструктуры от бизнес логи c бобы. Тем не менее, поскольку вы используете @EnableBatchProcessing, нет необходимости настраивать репозиторий заданий, модуль запуска заданий и т. Д. c. Цель этой аннотации состоит в том, чтобы предоставить вам эти инфраструктурные компоненты, см. его javado c.

Моя цель - просто успешно автоматически подключить класс JobLauncherTestUtils.

Поскольку вы используете @SpringBatchTest, нет необходимости создавать JobLauncherTestUtils вручную (в вашем методе jobLauncherTestUtils()), цель этой аннотации - импортировать его для вас, см. его Джавадо c. Вот типичное использование:

@RunWith(SpringRunner.class)
@SpringBatchTest
@ContextConfiguration(classes = MyBatchJobConfiguration.class)
public class MyBatchJobTests {

    @@Autowired
    private JobLauncherTestUtils jobLauncherTestUtils;

    @@Autowired
    private JobRepositoryTestUtils jobRepositoryTestUtils;

    @Before
    public void clearJobExecutions() {
        this.jobRepositoryTestUtils.removeJobExecutions();
    }

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

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

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

}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...