单位:如何使用jUnit和Mockito编写测试用例

时间:2011-05-17 20:23:45

标签: java unit-testing junit mockito

我对Mockito以及jUnit和TDD一般都是新手,我尝试学习正确的TDD方法。我需要几个例子才能启动我的大脑。所以请帮帮我

所以我有一个方法getNameInc(String dirPath, String filenName)。因此,给定bankAccount.pdf之类的文件名,如果在此文件夹中没有文件名bankAccount.pdf,则返回bankAccountAA.pdf。如果存在一个bankAccount.pdf,则return bankAccountBB.pdf incrementAA-ZZ。当它达到ZZ时,它会回滚到AA。我已经实现了这个方法的逻辑。如何使用Mockiti和jUnit对此方法进行单元测试?

修改

这是涉及的类和方法。

public class PProcessor{

    private final Map<Integer, String> incMap = new HashMap<Integer, String>();

    private String getNameInc(String dirPath, String filenName){
         String[] nameList = new File(dirPath).list(new FilenameFilter(){
            public boolean accept(File file, String name) {
                //only load pdf files
                return (name.toLowerCase().endsWith(".pdf"));
            }
        });
        //Return the number of occurance that a given file name appear
        //inside the output folder.
        int freq = 0;
        for(int i=0; i<nameList.length; i++){

            if(fileName.equals(nameList[i].substring(0, 8))){
                freq++;
            }
        }
        return incMap.get(freq);
    }

    private void generateIncHashMap(){
        incMap.put(new Integer(0), "AA");
        incMap.put(new Integer(1), "BB");
        incMap.put(new Integer(2), "CC");
        ...
    }
}
将在构造函数中调用

generateIncHashMap()来预生成哈希映射

2 个答案:

答案 0 :(得分:7)

我正在尝试测试你的getNameInc(..)方法。当你调用它时,它会查找你指定的目录中的文件,并根据它找到的内容装饰你给它的名字。

要使类可单元测试,您应该抽象对文件系统的依赖,以便在模拟中,您可以模拟您想要的任何目录内容。您的类将接受此接口的实例作为依赖项,并调用它以查找目录中的内容。当您在程序中使用该类时,您将提供此接口的实现,该实现委派给JDK文件系统调用。当您对该类进行单元测试时,您将提供此接口的Mockito模拟。

避免在FilesystemImpl类中添加太多逻辑,因为您无法为其编写严格的单元测试。保持它是一个非常简单的文件系统包装器,所以所有智能的东西都在Yourclass中,你将为它编写大量的单元测试。

public interface Filesystem {
    boolean contains(String dirpath, String filename);
}

public class FilesystemImpl {
    boolean contains(String dirpath, String filename) {
        // Make JDK calls to determine if the specified directory has the file.
        return ...
    }
}

public class Yourmainclass {
    public static void main(String[] args) {

         Filesystem f = new FilesystemImpl();
         Yourclass worker = new Yourclass(f);
         // do something with your worker
         // etc...
    }
}

public class Yourclass {
    private Filesystem filesystem;

    public Yourclass(Filesystem filesystem) {
        this.filesystem = filesystem;
    }

    String getNameInc(String dirpath, String filename) {
       ...
       if (filesystem.contains(dirpath, filename) {
          ...
       }
    }

}

public class YourclassTest {

   @Test
   public void testShouldAppendAAWhenFileExists() {
       Filesystem filesystem = Mockito.mock(Filesystem.class);
       when(filesystem.contains("/some/mock/path", "bankAccount.pdf").thenReturn(true);
       Yourclass worker = new Yourclass(filesystem);
       String actual = worker.getNameInc("/some/mock/path", "bankAccount.pdf");
       assertEquals("bankAccountAA.pdf", actual);
   }

   @Test
   public void testShouldNotAppendWhenFileDoesNotExist {
       Filesystem filesystem = Mockito.mock(Filesystem.class);
       when(filesystem.contains("/some/mock/path", "bankAccount.pdf").thenReturn(false);
       Yourclass worker = new Yourclass(filesystem);
       String actual = worker.getNameInc("/some/mock/path", "bankAccount.pdf");
       assertequals("bankAccount.pdf", actual);
   }
}

由于测试之间存在大量重复,您可能会创建一个设置方法并在那里完成一些工作,并为要使用的测试创建一些实例变量:

    private static final String TEST_PATH = "/some/mock/path";
    private static final String TEST_FILENAME = "bankAccount.pdf";
    private Filesystem filesystem;
    private Yourclass worker;

    @Before
    public void setUp() {
        filesystem = Mockito.mock(Filesystem.class);
        worker = new Yourclass(filesystem);
    }

    @Test
   public void testShouldAppendAAWhenFileExists() {
       when(filesystem.contains(TEST_PATH, TEST_FILENAME).thenReturn(true);
       String actual = worker.getNameInc(TEST_PATH, TEST_FILENAME);
       assertEquals("bankAccountAA.pdf", actual);
   }

   etc...

答案 1 :(得分:5)

对于你所描述的内容,我不会打扰Mockito,似乎没有什么可以模拟的(因为它很容易操纵文件系统)。

我会测试......   - 如果我调用getNameInc并且没有匹配的文件会发生什么   - 如果我调用getNameInc并且已经有文件AA-YY会发生什么   - 如果我调用getNameInc并且文件ZZ已经存在

会发生什么

TDD的重点是你应该已经编写了这些测试,然后实现了代码以使测试通过。因为你已经有了代码,所以你不会真正做TDD。