Java中的模拟文件 - Mock内容 - Mockito [英] Mocking Files in Java - Mock Contents - Mockito

查看:1235
本文介绍了Java中的模拟文件 - Mock内容 - Mockito的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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



我已经尝试过像嘲笑文件一样的解决方案,并嘲笑尽可能多的属性,然后还可以用文件撰写者/缓冲写作员写入,但是那些因为他们需要规范的道路。任何人找到一个解决方案,而不是这个或类似的,但是我接近这个错误?



我一直这样做:

  private void mocking(){
文件badHTML = mock(File.class);
//设置badHTML
的属性(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是一个字符串,内容我想放入文件,
可以只是你想要的任何
* /
bw.append badHTMLText);
bw.close();

} catch(IOException ex){
System.err.println(ex);
}
}

任何想法或指导都将非常有帮助。
此后我基本上尝试从文件中读取另一个类。我会尝试模拟一些输入流,但是另一个类不需要输入流,因为它是项目的io处理类。

解决方案

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




  • 不要试图模拟一个文件 。只是不要太多的本土事情依赖于它。

  • 如果可以,将您的I / O处理代码分成打开文件的一半文件并将其转换为 Reader ,而从$ code> Reader 中解析HTML的一半。

  • 在这一点上,你根本不需要模拟 - 只需构造一个 StringReader 来模拟数据源。

  • 您的单元测试相当不错,您可能还想编写一个使用临时文件,并确保它读取正确。 (谢谢Brice添加那个提示!)



不要害怕重构你的课程,使测试更容易,如下所示: / p>

  class YourClass {
public int method(File file){
// do everything here,which is为什么它需要一个模拟
}
}

class YourRefactoredClass {
public int method(File file){
return methodForTest(file.getName() ,file.isFile(),
file.isAbsolute(),新的FileReader(文件));
}

/ **仅用于测试。 * /
int methodForTest(
String name,boolean isFile,boolean isAbsolute,Reader fileContents){
//实际上在这里计算
}
}

class YourTest {
@Test public int methodShouldParseBadHtml(){
YourRefactoredClass yrc = new YourRefactoredClass();
assertEquals(42,yrc.methodForTest(
bad.html,true,false,new StringReader(badHTMLText));
}
}

此时,方法中的逻辑非常简单,不值得测试,
methodForTest 中的逻辑非常容易访问,您可以大量测试。


I'm pretty new to mocking, and I've been trying to mock the actual contents (essentially create a virtual file in memory alone) so that no data is written to disk at any point.

I've tried solutions like mocking the file and mocking as many of the properties that I can figure out as much as possible, an then also writing into it with a filewriter/bufferedwriter, but those don't work well, since they need canonical paths. Anyone found a solution other than this or similar, but that I'm approaching this wrong?

I've been doing it like this:

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

Any ideas or guidance would be very helpful. Somewhere after this i basically try to read from the file using another class. I would try to mock some sort of input stream, but the other class doesn't take an inputstream, since it's the io handling class for the project.

解决方案

You seem to be after contradictory goals. On the one hand, you're trying to avoid writing data to disk, which isn't a bad goal in tests. On the other, you're trying to test your I/O-handling class, which means you'll be working with system utilities that assume that your File will work with native calls. As such, here's my guidance:

  • Don't try to mock a File. Just don't. Too many native things depend on it.
  • If you can, split your I/O-handling code into the half that opens a File and turns it into a Reader, and the half that parses HTML out of the Reader.
  • At that point, you don't need a mock at all--just construct a StringReader to simulate the data source.
  • While that handles your unit tests pretty well, you may also want to write an integration test that uses a temporary file and ensure that it reads right. (Thanks Brice for adding that tip!)

Don't be afraid to refactor your class to make testing easier, as here:

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

At this point the logic in method is so straightforward it's not worth testing, and the logic in methodForTest is so easy to access that you can test it heavily.

这篇关于Java中的模拟文件 - Mock内容 - Mockito的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆