本文介绍了抛出ClassCastException的ItemReader集成测试的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试对ItemReader进行集成测试-这是课程:

I am trying to integration test an ItemReader - here is the class:

@Slf4j
public class StudioReader implements ItemReader<List<Studio>> {

   @Setter private zoneDao zoneDao;

   @Getter @Setter private BatchContext context;

   private AreaApi areaApi = new AreaApi();

   public List<Studio> read() throws Exception {

      return areaApi.getStudioLocations();
  }

这是我的bean.xml:

Here is my bean.xml:

<bean class="org.springframework.batch.core.scope.StepScope" />
<bean id="ItemReader" class="com.sync.studio.reader.StudioReader" scope="step">
   <property name="context" ref="BatchContext" />
   <property name="zoneDao" ref="zoneDao" />
</bean>

这是我要编写的测试:

@ContextConfiguration(locations = {
        "classpath:config/studio-beans.xml",
        "classpath:config/test-context.xml"})
@TestExecutionListeners({
        DependencyInjectionTestExecutionListener.class,
        StepScopeTestExecutionListener.class })
public class StudioSyncReaderIT extends BaseTest {

    @Autowired
    private ItemReader<List<Studio>> reader;

    public StepExecution getStepExecution() {
        JobParameters jobParameters = new JobParametersBuilder()
                .toJobParameters();
        StepExecution execution = createStepExecution(
                jobParameters);
        return execution;
    }
    @Before
    public void setUp() {
        ((ItemStream) reader).open(new ExecutionContext()); } //ClassCastException

    @Test
    @DirtiesContext
    public void testReader() throws Exception {
        assertNotNull(reader.read());
    }

    @After
    public void tearDown() {
        ((ItemStream) reader).close(); //ClassCastException
    }
}

我正在获取java.lang.ClassCastException:com.sun.proxy.$ Proxy36无法在之前和之后强制转换为ItemReader.我想念什么?我还需要为此设置其他任何内容(例如,配置xml中的任何注释或条目)吗?

I am getting java.lang.ClassCastException: com.sun.proxy.$Proxy36 cannot be cast to ItemReader on the Before and After. What am I missing? Is there anything else I need to setup for this (e.g. any annotations or entry in the config xml)?

推荐答案

您的问题是ItemReader不是ItemStream.如果要使用阅读器作为流,则StudioReader需要实现org.springframework.batch.item.ItemStreamReader.

Your problem is an ItemReader is not an ItemStream. your StudioReader need implementes org.springframework.batch.item.ItemStreamReader if you want use a reader as a stream.

import org.springframework.batch.item.ItemStreamReader;

public class StudioReader implements ItemStreamReader<List<Studio>>{
   ...
}

您可以使用泛型类型将类型T设置为多个接口,以避免在@Before& @After.

you can use Generic type to make the type T as multiple interfaces to avoid cast expression in @Before & @After.

public class StudioSyncReaderIT<T extends ItemReader<List<Studio>> & ItemStream >
            extends BaseTest {

   @Autowired
   private T reader;
   @Before
   public void setUp() {
     reader.open(new ExecutionContext());
   }

   @After
   public void tearDown() {
    reader.close();
   }

}

测试

@ContextConfiguration
@TestExecutionListeners({DependencyInjectionTestExecutionListener.class, StepScopeTestExecutionListener.class})
@RunWith(SpringJUnit4ClassRunner.class)
public class AutowireDependencyImplementedMultiInterfacesTest<T extends Supplier<List<String>> & Runnable & AutowireDependencyImplementedMultiInterfacesTest.Task> {
    @Autowired
    private T springTest;

    @Test
    public void inject() throws Throwable {
        assertThat(springTest, is(not(instanceOf(MockTask.class))));

        assertThat(springTest.get(), equalTo(singletonList("spring-test")));

        springTest.hasBeenRan(false);

        springTest.run();
        springTest.hasBeenRan(true);
    }


    @Configuration
    static class Config {

        @Bean("step")
        public StepScope stepScope() {
            return new StepScope();
        }

        @Bean
        @Scope(value = "step")
        public MockTask task() {
            return new MockTask("spring-test");
        }
    }

    interface Task {
        void hasBeenRan(boolean ran);
    }

    static class MockTask implements Supplier<List<String>>, Runnable, Task {

        private final List<String> descriptions;
        private boolean ran = false;

        public MockTask(String... descriptions) {
            this.descriptions = asList(descriptions);
        }

        @Override
        public void run() {
            ran = true;
        }

        @Override
        public List<String> get() {
            return descriptions;
        }

        public void hasBeenRan(boolean ran) {
            assertThat(this.ran, is(ran));
        }
    }
}

这篇关于抛出ClassCastException的ItemReader集成测试的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

07-07 13:26