我对模拟还很陌生,我一直在尝试模拟实际内容(本质上仅在内存中创建一个虚拟文件),以便在任何时候都不会将数据写入磁盘。
我尝试过一些解决方案,例如模拟文件并模拟尽可能多的我能找出的属性,然后使用文件写入器/缓冲写入器写入其中,但这些解决方案效果不佳,因为它们需要规范路径。有人找到了除此之外或类似的解决方案,但我的方法是错误的吗?
我一直这样做:
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);
}
}
任何想法或指导都会非常有帮助。
之后的某个地方我基本上尝试使用另一个类从文件中读取。我会尝试模拟某种输入流,但另一个类不接受输入流,因为它是项目的 io 处理类。
你似乎在追求相互矛盾的目标。一方面,您试图避免将数据写入磁盘,这在测试中并不是一个坏目标。另一方面,您正在尝试测试您的 I/O 处理类,这意味着您将使用假设您的系统实用程序File
将与本机调用一起使用。因此,这是我的指导:
- 不要试图嘲笑
File
。只是不要。太多原生的东西依赖于它。
- 如果可以的话,将 I/O 处理代码分成打开一个
File
并将其变成Reader
,以及从其中解析 HTML 的一半Reader
.
- 那时,你根本不需要模拟——只需构建一个StringReader来模拟数据源。
- 虽然这可以很好地处理您的单元测试,但您可能还想编写一个集成测试使用一个临时文件并确保其读取正确。 (感谢布莱斯添加该提示!)
不要害怕重构你的类以使测试更容易,如下所示:
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
非常容易访问,您可以对其进行大量测试。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)