Spring-Batch: тестирование пользовательского itemReader - PullRequest
1 голос
/ 17 февраля 2020

Я пытаюсь проверить свой пользовательский itemReader:

@Bean
@StepScope
MyMultiLineItemReader itemReader(@Value("#{stepExecutionContext['fileName']}") String filename) throws MalformedURLException {
MyMultiLineItemReader itemReader = new MyMultiLineItemReader();
itemReader.setDelegate(myFlatFileItemReader(filename));

return itemReader;
}

@Bean
@StepScope
public FlatFileItemReader<String> myFlatFileItemReader(@Value("#{stepExecutionContext['fileName']}") String filename) throws MalformedURLException {
return new FlatFileItemReaderBuilder<String>()
.name("myFlatFileItemReader")
.resource(new UrlResource(filename))
.lineMapper(new PassThroughLineMapper())
.build();
}

мой класс теста выглядит как

@Test
public void givenMockedStep_whenReaderCalled_thenSuccess() throws Exception {
    // given
    JobExecution jobExecution = new JobExecution(5l);
    ExecutionContext ctx = new ExecutionContext();
    ctx.put("fileName", "src/main/resources/data/input.txt");
    jobExecution.setExecutionContext(ctx);

    JobSynchronizationManager.register(jobExecution);
    StepExecution stepExecution = MetaDataInstanceFactory.createStepExecution(ctx);

    // when
    StepScopeTestUtils.doInStepScope(stepExecution, () -> {
     ...
     });
}

Когда я запускаю тестовый пример, процесс завершается неудачно, потому что параметр fileName имеет значение null.

Я ищу правильный способ тестирования itemReader.

Спасибо

1 Ответ

2 голосов
/ 18 февраля 2020

Вам не нужно создавать JobExecution и регистрировать его в JobSynchronizationManager, чтобы протестировать компонент ступенчатой ​​области. Достаточно издеваться над выполнением шага и использовать его в StepScopeTestUtils.doInStepScope. Вот полный пример:

import java.util.ArrayList;
import java.util.List;

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

import org.springframework.batch.core.StepExecution;
import org.springframework.batch.core.configuration.annotation.EnableBatchProcessing;
import org.springframework.batch.core.configuration.annotation.StepScope;
import org.springframework.batch.item.ExecutionContext;
import org.springframework.batch.item.file.FlatFileItemReader;
import org.springframework.batch.item.file.builder.FlatFileItemReaderBuilder;
import org.springframework.batch.item.file.mapping.PassThroughLineMapper;
import org.springframework.batch.test.MetaDataInstanceFactory;
import org.springframework.batch.test.StepScopeTestUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.ClassPathResource;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringRunner;

@RunWith(SpringRunner.class)
@ContextConfiguration(classes = StepScopedComponentTest.MyConfiguration.class)
public class StepScopedComponentTest {

    @Autowired
    private FlatFileItemReader<String> reader;

    @Test
    public void givenMockedStep_whenReaderCalled_thenSuccess() throws Exception {
        // given
        ExecutionContext ctx = new ExecutionContext();
        ctx.put("fileName", "data/input.txt");
        StepExecution stepExecution = MetaDataInstanceFactory.createStepExecution(ctx);

        // when
        List<String> items = StepScopeTestUtils.doInStepScope(stepExecution, () -> {
            List<String> result = new ArrayList<>();
            String item;
            reader.open(stepExecution.getExecutionContext());
            while ((item = reader.read()) != null) {
                result.add(item);
            }
            reader.close();
            return result;
        });

        // then
        Assert.assertEquals(2, items.size());
        Assert.assertEquals("foo", items.get(0));
        Assert.assertEquals("bar", items.get(1));
    }

    @Configuration
    @EnableBatchProcessing
    static class MyConfiguration {

        @Bean
        @StepScope
        public FlatFileItemReader<String> myFlatFileItemReader(@Value("#{stepExecutionContext['fileName']}") String filename) {
            return new FlatFileItemReaderBuilder<String>()
                    .name("myFlatFileItemReader")
                    .resource(new ClassPathResource(filename))
                    .lineMapper(new PassThroughLineMapper())
                    .build();
        }
    }

}

Этот тест проходит, предполагая, что ресурс пути к классу data/input.txt содержит строки foo и bar.

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