如何解决JUnit/Mockito:如何模拟或创建私有成员变量
我有一个私有字符串变量 filePath,它将在 SpringBoot 的 execute(..)
方法中设置,然后该值将在另一个方法中使用,该方法将从该 execute(..)
内部调用。
@Component("filebatchjobtask")
public class FileBatchJobTask extends BaseFileBatchJobTask implements tasklet {
private String filePath; // PRIVATE VARIABLE THAT WILL BE USED IN A CALL
private static final CalLogger LOGGER = CalLoggerFactory.getLogger(FileBatchJobTask.class);
@Override
public RepeatStatus execute(final StepContribution stepContribution,final ChunkContext chunkContext) throws Exception {
// INITIALIZE PRIVATE VARIABLE HERE
filePath = chunkContext.getStepContext().getJobParameters().get(Constants.FILEPATH).toString();
processeFile(); // METHOD CALL WHERE FILEPATH INITIALIZED ABOVE WILL BE USED
return RepeatStatus.FINISHED;
}
@Override
protected void processeFile() throws IOException {
LOGGER.warn("FileBatchJobTask:processeFile():: Directory to process files: " + filePath);
File[] filelist = geteFiles(filePath); // THIS IS THE CALL I WANT TO MOCK
if (filelist == null || filelist.length < 1) {
LOGGER.warn("FileBatchJobTask: No eFiles available to process");
return;
}
LOGGER.warn("Total number of files to process: " + filelist.length);
}
对应的测试如下:
//@RunWith(powermockrunner.class)
@RunWith(MockitoJUnitRunner.class)
public class FileBatchJobTaskTest extends BaseFileBatchJobTaskTest {
@InjectMocks
FileBatchJobTask fileBatchJobTask;
@Override
BaseFileBatchJobTask createFileBatchJobTask() {
return fileBatchJobTask;
}
@Test
public void processeFile() {
BaseFileBatchJobTask batchJobTask = Mockito.spy(createFileBatchJobTask());
// THIS resourceDir is the I want to use instead of filePath variable in tests here and pick file from this test resource path
Path resourceDir = Paths.get("src","test","resources","data","validation");
resourcePath = resourceDir.toFile().getAbsolutePath();
File fileDir = new File(resourcePath);
File[] files = fileDir.listFiles(new FileFilter() {
@Override
public boolean accept(final File pathname) {
String name = pathname.getName().toLowerCase();
return name.endsWith(".xml") && pathname.isFile();
}
});
doReturn(files).when(batchJobTask).geteFiles(anyString()); // THIS IS THE CALL I AM TRYING TO MOCK
try {
fileBatchJobTask.processeFile();
Assert.assertTrue(true);
} catch (...) {
}
}
这是基类
class BaseFileBatchJobTask {
protected File[] geteFiles(final String eFileDirPath) {
File fileDir = new File(eFileDirPath); // NPE as eFileDirPath is null
File[] files = fileDir.listFiles(new FileFilter() {
@Override
public boolean accept(final File pathname) {
String name = pathname.getName().toLowerCase();
return name.endsWith(".xml") && pathname.isFile();
}
});
return files;
}
}
ERROR
:当测试运行时,我得到 NPE,执行 getEFiles() 并且 filePath 为空。由于我是在嘲笑,它不应该进入该方法的实际实现。但是,它似乎没有像预期的那样被嘲笑,因此需要帮助来解决问题。
还查找了很多 SO 帖子,但无法弄清楚问题所在,因此如果您不知道答案,请不要将其标记为重复 :)
解决方法
您需要在 jobTask 的间谍版本上调用 processeFile()
,而不是在原始版本上调用。想想间谍是被监视对象的包装器,它拦截模拟调用。
简而言之,只需在 batchJobTask
块中使用 try-catch
,如下所示:
try {
batchJobTask.processeFile();
Assert.assertTrue(true);
} catch (...) {
}
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。