简体   繁体   English

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

[英]How to test a method which creates directories and file system

This is my method, which creates a file system when gets called. 这是我的方法,它在被调用时创建一个文件系统。

/**
     * 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);
            }
        }
    }

Now I must write a unit test for this method. 现在,我必须为此方法编写一个单元测试。 I have read several posts related to "TemporaryFolder" in Mockito and "Rule" annotation, but to tell the the truth, I do not know which approach I need. 我已经阅读了Mockito中与“ TemporaryFolder”和“ Rule”注释相关的几篇文章,但说实话,我不知道我需要哪种方法。 Anybody please help me to find a way for testing this method. 任何人都可以帮助我找到测试此方法的方法。 If there is a necessity for providing the helper methods used in aforementioned method, I can provide them. 如果有必要提供上述方法中使用的辅助方法,我可以提供它们。

One of the aproaches may be to create wrapper class for File and then provide it into the class that this method resides. 方法之一是为File创建包装器类,然后将其提供给此方法所在的类。 Then you will be able to mock it with mockito and verify whether proper methods were invoked. 然后,您将能够使用Mockito模拟它并验证是否调用了正确的方法。

Normally you should not test classes that are not in your project, ( File for example). 通常,您不应该测试项目中没有的类(例如File )。 This is not a good practice while writing unit tests. 在编写单元测试时,这不是一个好习惯。 The thing that you can test is behavior of your method, that is whether proper external methods were invoked. 您可以测试的是方法的行为,即是否调用了正确的外部方法。

You should also remember to check if the validation is working by providing various inputs in your unit tests. 您还应该记得通过在单元测试中提供各种输入来检查验证是否有效。

I suggest to use JUnit's TemporaryFolder rule. 我建议使用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() );
  }
}

I recommend to use AssertJ as assertion library because it has nice assertions for files. 我建议使用AssertJ作为断言库,因为它对文件有很好的断言。

The real issue here: you created hard to test code - because you are implementing more than one responsibility in this method. 真正的问题是:您创建了难以测试的代码-因为您要在此方法中实现多个职责 Instead of collecting file names, and then creating them, your method could for example look like this: 而不是收集文件名然后创建它们,例如,您的方法可能如下所示:

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)

The above is merely meant as "pseudo code" to give you some ideas. 以上内容仅是为了给您一些想法的“伪代码”。 The core point is: by extracting behavior into its own class/interface you enable yourself to test each functionality separately. 核心点是:通过行为提取到其自己的类/接口中,可以使您自己分别测试每个功能。 And later on, you can use dependency injection to make that functionality available to more complex methods. 然后,您可以使用依赖注入使该功能可用于更复杂的方法。 You see - you could now mock all those "service" objects; 您会看到-现在可以模拟所有这些“服务”对象; and all of a sudden you only talk about verifying that you pass a certain list of File objects to another method. 突然之间,您仅谈论验证将文件对象的特定列表传递给另一种方法。

Long story short: as usual the answer is: write testable code. 长话短说:通常答案是:编写可测试的代码。 Follow clean code rules, such as single responsibility principle . 遵循干净的代码规则,例如单一职责原则 And when you do that, the quality of your production code will improve; 当您这样做时,您的生产代码的质量将会提高。 and your tests will be much simpler to write down. 并且您的测试将更容易写下来。 Without the need to do fake file system operation all over the place. 无需到处进行伪造的文件系统操作。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM