使用@MockBean 模拟带有@BeforeStep 的ItemReader 会向带有@Beforestep 注释的许多方法抛出异常。我该如何解决?
Using @MockBean to mock an ItemReader with @BeforeStep Throws Exception to many methods with @Beforestep anotation. How do I solve it?
我有自己的 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
模拟 ItemReader 时,应用程序上下文抛出:
java.lang.IllegalArgumentException: found more than one method on target class [Reader$MockitoMock8106910] with the annotation type [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);
}
我已经能够重现您的问题。在那之后,我用你的 Reader.
的 child class 替换了模拟
@Component
public class ChildReader extends Reader{
public void init(StepExecution stepExecution){
super.init(stepExecution);
}
}
这给出了同样的例外。
在运行时,Mockito 还会创建 Reader 的 subclass。我认为这是导致您的问题的原因。
在此 post 中,描述的是同一问题:
http://forum.spring.io/forum/spring-projects/batch/98067-beforestep-in-abstract-class
我找不到任何关于它被修复的参考。
要解决此问题,您可以将要模拟的代码提取到单独的 class 并模拟该 class。一个合乎逻辑的地方是 StepExecutionListener。
https://docs.spring.io/spring-batch/trunk/apidocs/org/springframework/batch/core/StepExecutionListener.html
希望这对您有所帮助....
在你的 class 中实现 stepexecutionlistener 接口并重写 before 和 after 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;
}
}
如果您将 MockBean 更改为接口,应该会修复
而不是
@MockBean
private Reader reader;
做
@MockBean
private ItemReader<Integer> reader;
如果你正在模拟它,你不应该需要你的具体 class 的内容。
对我来说,使用 mock(ClassToBeMocked.class)
而不是 @MockBean
!
我有自己的 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
模拟 ItemReader 时,应用程序上下文抛出:
java.lang.IllegalArgumentException: found more than one method on target class [Reader$MockitoMock8106910] with the annotation type [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);
}
我已经能够重现您的问题。在那之后,我用你的 Reader.
的 child class 替换了模拟@Component
public class ChildReader extends Reader{
public void init(StepExecution stepExecution){
super.init(stepExecution);
}
}
这给出了同样的例外。 在运行时,Mockito 还会创建 Reader 的 subclass。我认为这是导致您的问题的原因。
在此 post 中,描述的是同一问题: http://forum.spring.io/forum/spring-projects/batch/98067-beforestep-in-abstract-class 我找不到任何关于它被修复的参考。
要解决此问题,您可以将要模拟的代码提取到单独的 class 并模拟该 class。一个合乎逻辑的地方是 StepExecutionListener。 https://docs.spring.io/spring-batch/trunk/apidocs/org/springframework/batch/core/StepExecutionListener.html
希望这对您有所帮助....
在你的 class 中实现 stepexecutionlistener 接口并重写 before 和 after 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;
}
}
如果您将 MockBean 更改为接口,应该会修复
而不是
@MockBean
private Reader reader;
做
@MockBean
private ItemReader<Integer> reader;
如果你正在模拟它,你不应该需要你的具体 class 的内容。
对我来说,使用 mock(ClassToBeMocked.class)
而不是 @MockBean
!