如何测试创建目录和文件系统的方法

时间:2017-05-20 10:53:23

标签: java junit mockito

这是我的方法,它在被调用时创建一个文件系统。

/**
     * Process all messages from {@code messagesDir} directory and save results in {@code resultsDir}
     *
     * @param messagesDir      messages directory
     * @param resultsDir       results directory
     * @param logDirectory     directory where should be written logs
     * @param cleanupResultDir whether cleanup result directory
     * @throws PtfProcessorException if provided {@code messagesDir} is invalid directory or there was comparision exception
     */
    public void processMessages(String messagesDir, String resultsDir, String logDirectory, boolean cleanupResultDir)
            throws PtfProcessorException {
        // check if the directories are valid
        checkIsValidDirectory(messagesDir);
        checkIsValidDirectory(resultsDir);

        // get operations directories
        final File[] operationsDirsFiles = getInnerDirs(messagesDir);

        // get results directory and clean up it if cleanupResultDirectory is true
        final File resultsDirFile = new File(resultsDir);
        if (cleanupResultDir) {
            cleanUpDirectory(resultsDirFile);
        }

        // compare messages by operation bases
        for (File operationDirFile : operationsDirsFiles) {
            // operation log directory file
            final File logOperationDirFile = new File(logDirectory, operationDirFile.getName());
            try {
                compareOperationMessages(operationDirFile, resultsDirFile, logOperationDirFile);
            } catch (PtfProcessorException e) {
                writeExceptionLog("Exception while comparing operation: " + operationDirFile.getName(),
                        e, logOperationDirFile);
            }
        }
    }

现在我必须为这个方法编写一个单元测试。我在Mockito读了几篇与“TemporaryFolder”相关的帖子和​​“Rule”注释,但说实话,我不知道我需要哪种方法。任何人请帮我找到测试这种方法的方法。 如果有必要提供上述方法中使用的辅助方法,我可以提供它们。

3 个答案:

答案 0 :(得分:0)

其中一个方法可能是为File创建包装类,然后将其提供给此方法所在的类。然后,您将能够使用mockito进行模拟,并验证是否调用了正确的方法。

通常,您不应该测试项目中没有的类,(例如File)。在编写单元测试时,这不是一个好习惯。您可以测试的是您的方法的行为,即是否调用了适当的外部方法。

您还应该记得通过在单元测试中提供各种输入来检查验证是否有效。

答案 1 :(得分:0)

我建议使用JUnit的TemporaryFolder规则。

public class YourTest {
  @Rule
  public final TemporaryFolder folder = new TemporaryFolder();

  @Test
  public void verifySomeFileBehaviour() throws Exception {
    File messagesDir = folder.newFolder();
    File reportsDir = folder.newFolder();
    File logsDir = folder.newFolder();

    //create your object and then
    yourObject.processMessages(
      messagesDir.getAbsolutePath(),
      reportsDir.getAbsolutePath(),
      logsDir.getAbsolutePath(),
      true
    );

    //now you can verify the contents. E.g.
    assertTrue( new File( messagesDir, "firstMessage.txt" ).exists() );
  }
}

我建议使用AssertJ作为断言库,因为它对文件有很好的断言。

答案 2 :(得分:0)

真正的问题是:您创建了 hard 来测试代码 - 因为您在此方法中实施了多个职责。您的方法可以例如如下所示,而不是收集文件名,然后创建它们:

public void processMessages(String messagesDir, String resultsDir, String logDirectory, boolean cleanupResultDir)
        throws PtfProcessorException {
    directoryValidator.validate(messagesDir, resultsDir);

    final File[] operationsDirsFiles = getInnerDirs(messagesDir);

    cleanupService.cleanup(cleanupResultDir, resultsDirFile);
    fileService.create(operationsDirsFiles)

以上仅仅是指“伪代码”,为您提供一些想法。核心要点是:通过行为提取到自己的类/接口中,您可以自己分别测试每个功能。稍后,您可以使用依赖注入使该功能可用于更复杂的方法。你看 - 你现在可以模拟所有那些“服务”对象;而且你突然只谈到验证你是否将某个File对象列表传递给另一个方法。

长话短说:通常答案是:写testable代码。遵循干净的代码规则,例如单一责任原则。当您这样做时,您的生产代码的质量将得到改善;写下来你的测试会更简单。无需在整个地方进行文件系统操作。