关于测试private methods

本文主要探讨Java中私有方法的测试问题。介绍了使用JUnit和SuiteRunner测试私有方法的四种基本方法,包括不测试、给予包访问权限、使用嵌套测试类和反射。同时指出多数情况下可通过测试调用私有方法的其他方法间接测试,但也存在直接测试的需求。

看看Java中是如何进行private methods的测试的

Testing Private Methods with JUnit and SuiteRunner

So whether you are using JUnit or SuiteRunner, you have the same four basic approaches to testing private methods:

  • Don't test private methods.
  • Give the methods package access.
  • Use a nested test class.
  • Use reflection.

当然更多的建议不要对private methods测试

Approach 1: Don't Test Private Methods

As I mentioned in the introduction, I first heard the advice to suppress my occasional urges to test private methods from Daniel Steinberg. But Daniel is not only source of this advice that I have encountered. It seems to be a common attitude in the Java community. For example, the JUnit FAQ [4] states:

Testing private methods may be an indication that those methods should be moved into another class to promote reusability.

Charles Miller expressed a similar point of view in his weblog [5]:

If you have a thorough suite of tests for a class's exposed (non-private) interface, those tests should, by their nature, verify that any private method within the class also works. If this isn't the case, or if you have a private method so complex that it needs to be tested out of the context of its public callers, I would consider that a code-smell.

And Dave Thomas and Andy Hunt, in their book Pragmatic Unit Testing [6], write:

In general, you don't want to break any encapsulation for the sake of testing (or as Mom used to say, "don't expose your privates!"). Most of the time, you should be able to test a class by exercising its public methods. If there is significant functionality that is hidden behind private or protected access, that might be a warning sign that there's another class in there struggling to get out.

I believe all this advice. Most of the time, private methods can be most effectively tested via approach 1, indirectly by testing the package-level, protected, and public methods that call them. But inevitably, some people in some situations will feel that directly testing a private method is the right thing to do.

In my case, I tend to create many private utility methods. These utility methods often do nothing with instance data, they just operate on the passed parameters and return a result. I create such methods to make the calling method easier to understand. It is a way to manage the complexity of the implementation of the class. Now, if I extract the private method out of a method that already works and has good unit test coverage, then those existing unit tests will likely suffice. I needn't write more unit tests just for the private method. But if I want to write the private method before its calling method, and I want to write the unit tests before writing the private method, I'm back to wanting to directly test the private method. In the case of private utility methods, I don't feel my urge to directly test the methods is, as the JUnit FAQ put it, "an indication that those methods should be moved into another class to promote reusability." These methods are really only needed in the class in which they reside, and in fact are often only called by one other method.

Another reason I sometimes feel the urge to test private methods directly is that I tend to think of unit testing as helping me achieve a robust system by building that system out of robust parts. Each part is a "unit" for which I can write "unit tests." The unit tests help me ensure each unit is functioning correctly, which in turn helps me build a system that functions correctly as a whole. The primary unit I think in terms of when programming in Java is the class. I build systems out of classes, and unit tests give me confidence that my classes are robust. But to some extent I also feel the same way about the private methods out of which I compose package-access, protected, and public methods. These private methods are units that can be tested individually. Such unit tests give me confidence that the private methods are working correctly, which helps me build package-access, protected, and public methods that are robust.

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值