单元测试时后门 java 访问的替代方案
我正在尝试使用许多私有方法对一个类进行单元测试。每个私有方法都可能相当广泛。
我可以将方法包设置为作用域(这会导致警告),或者我可以使用下面的代码来测试它:
Method method = instance.getClass().getDeclaredMethod("methodName");
method.setAccessible(true);
Object object = method.invoke(instance);
assertNotNull(object);
该类不是“上帝对象”,并且它的大多数方法都会触及它的所有字段。
关于如何更好地处理这个问题有什么建议吗?
I'm trying to unit test a class with a number of private methods. Each of the private methods can be rather extensive.
I can either make the method package scoped (which causes a warning), or I can use the code below to test it:
Method method = instance.getClass().getDeclaredMethod("methodName");
method.setAccessible(true);
Object object = method.invoke(instance);
assertNotNull(object);
The class is not a "God Object" and most of its methods touch all of its fields.
Any suggestions on how this can be handled better?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
测试私有方法也可能是一种测试味道。
我的参考是一本优秀的书 http://www.manning.com/rainsberger/
You应该测试行为而不是方法:粒度有点不同。
<块引用>
示例 1:要测试 Pile,如何在不互相引用的情况下测试
push
和pop
?但测试全局行为是可能的。这提醒我们,即使对于测试来说,对象也是正确的粒度,而不是方法。示例2:当你想测试几个对象之间的交互时,逐个方法测试显然是不正确的,你想测试一个全局行为。
如果一个方法不是公共的,它就不能被外界调用,并且它的行为定义也不太严格。但最重要的是,如果您测试私有方法,以后将无法重构代码。因此测试应该只在公共代码上进行。
Testing private methods may also be a testing-smell.
My reference is the excellent book http://www.manning.com/rainsberger/
You are supposed to test behaviors instead of method : the granularity is a bit different.
If a method is not public, it cannot be called by the outside world, and it's behaviour is less strictly defined. But more than everything, if you test a private method, you will not be able to refactor your code later. So testing should be done on public code only.
克莱是对的。
但是,如果您正在使用遗留代码并且必须处理私有方法中的依赖关系,最后的选择是 JMockit。我还没有使用过它,但在单元测试的艺术中阅读了它。它应该能够将呼叫从原始班级交换到您的假班级。
使用它来打破对其他对象的依赖关系,以便您可以测试公共方法,而不是测试私有方法。并将其用作重构解耦设计过程中的安全网。
KLE is right.
However, if you're working with legacy code and you have to deal with dependencies in private methods, one last-ditch option is JMockit. I haven't used it, but read about it in The Art of Unit Testing. It's supposed to be able to swap calls from the original class to your fake class.
Use this for breaking dependencies on other objects so you can test the public methods, not for testing private methods. And use it as a safety net on the way towards refactoring to a decoupled design.
如果您还没有使用它,这可能有点困难……但是 Groovy 确实非常适合违反单元测试的访问限制……您可以直接访问并调用这些方法,就好像它们是公共的一样,无需额外的反射。
This is probably a stretch if you're not already using it... but Groovy is really great for violating access restrictions for unit testing... you can just reach in and call the methods as though they were public without additional reflection.
我很好奇当您打包作用域方法时会收到什么样的警告,但无论如何,解决此类问题的方法是使测试成为对象的静态内部类。这可能需要权衡;如果部署大小是一个重要问题,您可能需要将该类排除在代码打包之外,并且您需要小心不要意外地将测试框架中的依赖项引入到生产代码中。
另一个潜在的选择是拥有一个静态内部类,它有助于公开您需要的方法,并且测试将使用它作为私有方法的传递。这里的缺点是,此类本质上将私有方法公开给任何想要使用该类的人,因此您必须小心地明确表示此类仅用于测试目的。
I'm curious what kind of warning you are getting when you package scope methods, but anyway, a way around this kind of issue is to make the test a static inner class of the object. This can have tradeoffs; you may need to exclude the class from being packaged with the code if deployment size is an important issue, and you need to be careful about accidentally introducing dependencies from the testing framework into the production code.
Another potential option is to have a static inner class that helps expose the methods you need, and the test would use it as a pass-through to the private methods. The downside here is that this class essentially exposes the private methods to anyone who wants to use the class, so you have to be careful to clearly express that this class is for testing purposes only.
您可以考虑使用反射。
You may consider using reflection.