无法在junit中模拟BufferedWriter类 [英] Unable to mock BufferedWriter class in junit

查看:100
本文介绍了无法在junit中模拟BufferedWriter类的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在源代码中使用了BufferedWriter对象

I am using a BufferedWriter object in my source code

BufferedWriter outputToErrorFile = new BufferedWriter(new FileWriter(file));
outputToErrorFile.append("some string");

我正在尝试在我的测试用例中模拟它,如下所示:

I am trying to mock it in my test case as follows:

BufferedWriter mockBufferedWriter = PowerMockito.mock(BufferedWriter.class);
PowerMockito.whenNew(BufferedWriter.class).withAnyArguments().thenReturn(mockBufferedWriter);
PowerMockito.when(mockBufferedWriter.append(Mockito.any(String.class))).thenThrow(new IOException());

但是,BufferedWriter不会被嘲笑,它总是进入实际的实现中.是因为它不能模拟BufferedWriter,因为它是一个具体的类吗?这是否意味着不能模拟任何java.io类?有没有办法模拟它,或者我做错了什么?

However, the BufferedWriter does not get mocked and it always goes into the actual implementation. Is it because that one cannot mock BufferedWriter as it is a concrete class? Does that mean none of the java.io classes can be mocked? Is there a way to mock it, or is there something I am doing wrong?

推荐答案

尽管您可能会遇到诸如<Writer()构造函数中的c0>(取决于模拟的完成方式以及模拟的IO类).

You can mock Java IO classes (including their constructors, so future instances also get mocked) with the JMockit library, though you will likely face difficulties such as a NullPointerException from the Writer() constructor (depending on how the mocking was done, and which IO classes were mocked).

但是,请注意,Java IO API包含许多交互类和深层继承层次结构.在您的示例中,可能还需要模拟FileWriter类,否则将创建一个实际文件.

However, note that the Java IO API contains many interacting classes and deep inheritance hierarchies. In your example, the FileWriter class would also probably need to be mocked, otherwise an actual file would get created.

此外,在应用程序代码中使用IO类通常只是实现细节,可以轻松更改.例如,您可以从IO流切换到编写器,从常规IO切换到NIO,或者使用新的Java 8实用程序.或使用第三方IO库.

Also, usage of IO classes in application code is usually just an implementation detail, which can easily be changed. You could switch from IO streams to writers, from regular IO to NIO, or use the new Java 8 utilities, for example. Or use a 3rd-party IO library.

最重要的是,尝试模拟IO类是一个非常糟糕的主意.如果(按照另一个答案中的建议)将客户端代码更改为具有Writer等等,甚至更糟.将注入到SUT中,则更糟.依赖注入不适合这种事情.

Bottom line, it's just a terribly bad idea to try and mock IO classes. It's even worse if (as suggested in another answer) you change the client code to have Writers, etc. injected into the SUT. Dependency injection is just not for this kind of thing.

相反,请在本地文件系统中使用 real 文件,最好从可以在测试后删除的测试目录中使用,并且/或者仅在读取时使用固定资源文件.本地文件快速而可靠,并导致更有用的测试.某些开发人员会说如果测试碰到文件系统,则它不是单元测试",但这只是教条式的建议.

Instead, use real files in the local file system, preferably from a test directory which can be deleted after the test, and/or use fixed resource files when only reading. Local files are fast and reliable, and lead to more useful tests. Certain developers will say that "a test is not a unit test if it touches the file system", but that's just dogmatic advice.

这篇关于无法在junit中模拟BufferedWriter类的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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