用 Java 模拟文件

编程入门 行业动态 更新时间:2024-10-27 10:27:44
本文介绍了用 Java 模拟文件 - Mock Contents - Mockito的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧! 问题描述

我对模拟非常陌生,我一直在尝试模拟实际内容(基本上是单独在内存中创建一个虚拟文件),以便在任何时候都不会将数据写入磁盘.

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?

我一直这样做:

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

任何想法或指导都会非常有帮助.在此之后的某个地方,我基本上尝试使用另一个类从文件中读取.我会尝试模拟某种输入流,但另一个类不接受输入流,因为它是项目的 io 处理类.

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.

推荐答案

您似乎追求相互矛盾的目标.一方面,您试图避免将数据写入磁盘,这在测试中并不是一个坏目标.另一方面,您正在尝试测试您的 I/O 处理类,这意味着您将使用假设您的 File 将与本机调用一起工作的系统实用程序.因此,这是我的指导:

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:

  • 不要试图模拟 File.只是不要.太多原生的东西依赖于它.
  • 如果可以,将 I/O 处理代码分成打开 File 并将其转换为 Reader 的一半,以及解析 HTML 的一半阅读器.
  • 此时,您根本不需要模拟——只需构建一个 StringReader 来模拟数据源.
  • 虽然可以很好地处理您的单元测试,但您可能还想编写一个使用 集成测试temp-file-in-java">临时文件 并确保它读取正确.(感谢 Brice 添加该提示!)
  • 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)); } }

此时method中的逻辑非常简单,不值得测试,并且 methodForTest 中的逻辑非常易于访问,您可以对其进行大量测试.

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 模拟文件

本文发布于:2023-10-31 07:08:54,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1545385.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:文件   Java

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!