【问题标题】:JUnit/Mockito: How to mock or create a private member variableJUnit/Mockito:如何模拟或创建私有成员变量
【发布时间】:2021-03-24 20:14:48
【问题描述】:

我有一个私有字符串变量 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 帖子,但无法找出问题所在,所以如果您不知道答案,请不要标记为重复 :)

【问题讨论】:

  • @Progman 我将 fileBatchJobTask 更新为对 Kathrin 下面评论的间谍。我不确定我应该在这里做什么,但只是尝试命中和尝试的方式。你知道它是如何正确完成的吗?
  • 所以我更新了,只保留了batchJobTask 的间谍,而不是fileBatchJobTask

标签: java mockito junit4 powermockito


【解决方案1】:

您需要在 jobTask 的间谍版本上调用 processeFile(),而不是在原始版本上。将间谍想象成一个围绕间谍对象的包装器,它拦截了模拟调用。

简而言之,只需在 try-catch 块内使用 batchJobTask,如下所示:

    try {    
    
        batchJobTask.processeFile();
        Assert.assertTrue(true);
    } catch (...) {

    }

【讨论】:

  • 我尝试了你的建议,它是否意味着像这样fileBatchJobTask = Mockito.spy(fileBatchJobTask);。还是一样的错误。
猜你喜欢
  • 2012-02-18
  • 2021-11-19
  • 1970-01-01
  • 2013-10-02
  • 1970-01-01
  • 1970-01-01
  • 2012-11-23
  • 1970-01-01
  • 2015-12-13
相关资源
最近更新 更多