在Java中嘲笑文件 – 模拟内容 – Mockito

我很嘲笑,我一直在试图嘲笑实际的内容(本质上是在内存中创build一个虚拟文件),以便在任何时候没有数据写入磁盘。

我尝试了一些解决scheme,比如嘲笑文件,嘲笑尽可能多的属性,然后用文件编写器/缓冲写入器写入文件,但是这样做效果不好,因为它们需要规范path。 任何人都find了这个或类似的解决scheme,但我接近这个错误?

我一直在这样做:

private void mocking(){ File badHTML = mock(File.class); //setting the properties of badHTML when(badHTML.canExecute()).thenReturn(Boolean.FALSE); when(badHTML.canRead()).thenReturn(Boolean.TRUE); when(badHTML.canWrite()).thenReturn(Boolean.TRUE); when(badHTML.compareTo(badHTML)).thenReturn(Integer.SIZE); when(badHTML.delete()).thenReturn(Boolean.FALSE); when(badHTML.getFreeSpace()).thenReturn(0l); when(badHTML.getName()).thenReturn("bad.html"); when(badHTML.getParent()).thenReturn(null); when(badHTML.getPath()).thenReturn("bad.html"); when(badHTML.getParentFile()).thenReturn(null); when(badHTML.getTotalSpace()).thenReturn(0l); when(badHTML.isAbsolute()).thenReturn(Boolean.FALSE); when(badHTML.isDirectory()).thenReturn(Boolean.FALSE); when(badHTML.isFile()).thenReturn(Boolean.TRUE); when(badHTML.isHidden()).thenReturn(Boolean.FALSE); when(badHTML.lastModified()).thenReturn(System.currentTimeMillis()); when(badHTML.mkdir()).thenReturn(Boolean.FALSE); when(badHTML.mkdirs()).thenReturn(Boolean.FALSE); when(badHTML.setReadOnly()).thenReturn(Boolean.FALSE); when(badHTML.setExecutable(true)).thenReturn(Boolean.FALSE); when(badHTML.setExecutable(false)).thenReturn(Boolean.TRUE); when(badHTML.setReadOnly()).thenReturn(Boolean.FALSE); try { BufferedWriter bw = new BufferedWriter(new FileWriter(badHTML)); /* badHTMLText is a string with the contents i want to put into the file, can be just about whatever you want */ bw.append(badHTMLText); bw.close(); } catch (IOException ex) { System.err.println(ex); } } 

任何想法或指导将是非常有益的。 在此之后的某个地方,我基本上试图从另一个类的文件中读取。 我会尝试模拟某种inputstream,但其他类不接受inputstream,因为它是项目的io处理类。

你似乎是在相互矛盾的目标之后。 一方面,您试图避免将数据写入磁盘,这在testing中不是一个坏的目标。 另一方面,您正试图testing您的I / O处理类,这意味着您将使用系统实用程序,假定您的File将使用本机调用。 因此,这是我的指导:

  • 不要试图嘲笑一个File 。 只是不要。 太多的本土东西都依赖于它。
  • 如果可以的话,将你的I / O处理代码分成一半,打开一个File ,并将其转换成一个Reader ,另一半将HTMLparsing出Reader
  • 在这一点上,你根本不需要模拟 – 只要构build一个StringReader来模拟数据源。
  • 虽然这样可以很好地处理你的unit testing,但你也可能想编写一个使用临时文件的集成testing ,并确保它的读取正确。 (感谢Brice添加该提示!)

不要害怕重构你的课堂,使testing更容易,如下所示:

 class YourClass { public int method(File file) { // do everything here, which is why it requires a mock } } class YourRefactoredClass { public int method(File file) { return methodForTest(file.getName(), file.isFile(), file.isAbsolute(), new FileReader(file)); } /** For testing only. */ int methodForTest( String name, boolean isFile, boolean isAbsolute, Reader fileContents) { // actually do the calculation here } } class YourTest { @Test public int methodShouldParseBadHtml() { YourRefactoredClass yrc = new YourRefactoredClass(); assertEquals(42, yrc.methodForTest( "bad.html", true, false, new StringReader(badHTMLText)); } } 

此时, method的逻辑非常简单,不值得进行testing,而methodForTest的逻辑非常容易访问,所以您可以大量地进行testing。