代码之家  ›  专栏  ›  技术社区  ›  PlickPlick

使用@MockBean模拟带有@BeforeStep的ItemReader会对带有@BeforeStep Anotion的许多方法引发异常。我该如何解决它?

  •  0
  • PlickPlick  · 技术社区  · 7 年前

    我有自己的ItemReader实现,它有两种方法。

    public class Reader implements ItemReader<Integer> {
    
        private final Logger logger = LoggerFactory.getLogger(getClass());
        private Iterator<Integer> iterator;
    
        @Override
        public Integer read() throws UnexpectedInputException, ParseException, NonTransientResourceException {
            if(iterator.hasNext()){
                return iterator.next();
            }
            return null;
        }
    
        @BeforeStep
        public void init(StepExecution stepExecution){
            List<Integer> integerList = (List<Integer>)stepExecution.getJobExecution().getExecutionContext().get(CKEY_ERROREVENT_IDS);
            this.iterator = integerList.iterator();
        }
    }
    

    当我尝试在spring批处理上下文中运行它并用 @MockBean 应用程序上下文引发:

    JAVAlang.IllegalArgumentException:在注释类型为[BeforeStep]的目标类[Reader$MockitoMock$368106910]上找到多个方法。

    下面是我如何开始这项工作。

    @MockBean
    private Reader reader;
    
    @Test
    public void readerTest(){
    JobParameters jobParameters = new JobParametersBuilder()
                .addString("triggerId", UUID.randomUUID().toString()).toJobParameters();
        JobExecution jobExecution = jobLauncher.run(processEventJob, jobParameters);
    }
    
    4 回复  |  直到 7 年前
        1
  •  1
  •   Maarten    7 年前

    我已经复制了你的问题。在那之后,我用你的读者的子类替换了mock。

    @Component
    public class ChildReader extends Reader{
    
        public void init(StepExecution stepExecution){
            super.init(stepExecution);
        }
    }
    

    这就产生了同样的例外。 在运行时,Mockito还创建为Reader的子类。我认为这是你的问题所在。

    在这篇文章中,描述了相同的问题: http://forum.spring.io/forum/spring-projects/batch/98067-beforestep-in-abstract-class 我找不到任何正在修复的引用。

    要解决此问题,可以将要模拟的代码提取到一个单独的类中,然后模拟该类。一个合乎逻辑的地方是StepExecutionListener。 https://docs.spring.io/spring-batch/trunk/apidocs/org/springframework/batch/core/StepExecutionListener.html

    希望这有帮助。。。。

        2
  •  1
  •   Madhankumar Baskaran    6 年前

    在类中实现stepexecutionlistener接口并重写前后的step方法这解决了我的问题不要使用@beforestep

    public class Reader implements ItemReader<Integer>,StepExecutionListener{
    
        private final Logger logger = LoggerFactory.getLogger(getClass());
        private Iterator<Integer> iterator;
    
        @Override
        public Integer read() throws UnexpectedInputException, ParseException, NonTransientResourceException {
            if(iterator.hasNext()){
                return iterator.next();
            }
            return null;
        }
    
       @Override
        public void beforeStep(StepExecution stepExecution){
            List<Integer> integerList = (List<Integer>)stepExecution.getJobExecution().getExecutionContext().get(CKEY_ERROREVENT_IDS);
            this.iterator = integerList.iterator();
        }
    
       @Override
        public ExitStatus afterStep(StepExecution stepExecution) {
            return null;
        }   
    }
    
        3
  •  0
  •   Tom Chamberlain    6 年前

    如果您将MockBean改为接口,应该修复

    而不是

    @MockBean
    private Reader reader;
    

    @MockBean
    private ItemReader<Integer> reader;
    

    如果你在模仿它,你不应该需要具体类的内容。

        4
  •  0
  •   csabinho    5 年前

    对我来说,使用 mock(ClassToBeMocked.class) 而不是 @MockBean 哦!