我有自己的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-batch上下文中运行它并使用@MockBean
模拟ItemReader时,应用程序上下文将抛出:
java.lang.IllegalArgumentException:在目标类[Reader $ MockitoMock $ 368106910]上找到了多个注释类型为[BeforeStep]的方法。
以下是我开始工作的方式。
@MockBean
private Reader reader;
@Test
public void readerTest(){
JobParameters jobParameters = new JobParametersBuilder()
.addString("triggerId", UUID.randomUUID().toString()).toJobParameters();
JobExecution jobExecution = jobLauncher.run(processEventJob, jobParameters);
}
答案 0 :(得分:1)
我已经能够重现您的问题。之后,我用你读者的子类替换了模拟。
@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
希望这会有所帮助......
答案 1 :(得分:0)
在您的类中实现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;
}
}
答案 2 :(得分:0)
如果将MockBean更改为接口,应该修复
代替
@MockBean
private Reader reader;
做
@MockBean
private ItemReader<Integer> reader;
如果要嘲笑它,则不需要具体类的内容。
答案 3 :(得分:0)
对我来说,它可以使用mock(ClassToBeMocked.class)
代替@MockBean
!