java实现mock,Java中的模拟文件 - Mock内容 - 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?

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.

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值