如何测试实用程序项目的最终方法和静态方法?
我正在尝试为一个项目实现单元测试,它使用一个遗留的“实用程序”项目,该项目充满了静态方法,并且许多类是最终的或者它们的方法是最终的。 我根本无法更新遗留项目。
JMock 和 EasyMock 都因最终方法而窒息,而且我没有看到测试静态调用的好方法。 有什么技术可以测试这些?
I'm trying to implement unit testing for aproject, it uses a legacy "utility" project that is littered with static methods and many of the classes are final or their methods are final. I'm not able to update the legacy project at all.
JMock and EasyMock both choke on final methods, and I don't see a nice way to test the static calls. What techniques are there to test these?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
如果您能够重构代码,则可以将对最终/静态方法的调用包装在简单的实例方法中,例如:
这允许您在单元测试中重写包装器方法以返回 Foo 的模拟实例。
或者,您可以使用 Powermock,它扩展了 Easymock(和 Mockito)以允许模拟最终和静态方法:
这是example 测试模拟静态最终方法,该示例还展示了如何模拟其他类型:
If you're able to refactor your code, you can wrap your calls to the final/static methods in simple instance methods, for example:
This allows you to override your wrapper method in the unit test to return a mock instance of Foo.
Alternatively you can use Powermock, which extends Easymock (and Mockito) to allow mocking of final and static methods:
Here's an example test mocking a static final method, the example shows how to mock some other types too:
间接/依赖注入的级别怎么样?
由于遗留实用程序项目是您的依赖项,因此创建一个接口将其与代码分开。 现在,该接口的实际/生产实现委托给遗留实用程序方法。
对于您的测试,您可以创建此界面的模拟,并避免与遗留实用程序交互。
How about a level of indirection / Dependency Injection?
Since the legacy utility project is your dependency, create an interface to separate it out from your code. Now your real/production implementation of this interface delegates to the legacy utility methods.
For your tests, you can create a mock of this interface and avoid interacting with the legacy utility thingie.
JMockit 允许您模拟静态方法和最终类。 我认为它使用了一些 classloadin-fu,尽管我还没有真正研究过它。
JMockit allows you to mock static methods and final classes. I assume it uses some classloadin-fu, although I haven't really looked into it.
正如已经指出的,可以使用JMockit。
一个例子:
As already pointed out, JMockit can be used.
An example:
如果您的不可重构方法使用 JNDI 之类的方法连接到另一个服务,我会考虑启动 JDNI 服务并使用您控制的存根填充它。 这很痛苦,但相对简单。 这可能意味着设置一个数据库或 JMS 监听器或其他什么,但应该有一个轻量级的 java 实现可以放入测试中。
If your non-refactorable method uses something like JNDI to connect to another service, I'd consider starting a JDNI service and populating it with stubs which you control. It's a pain but relatively straightforward. It may mean setting up a database or JMS listener or whatever but there should be a lightweight java implementation you can drop into the tests.
如果需要,JMock 与 JDave 一起可以模拟最终方法和类。 这里
是说明。 话虽这么说,我会将这些遗留代码(正如其他人已经建议的那样)视为外部依赖项并构建接口并模拟它们。 这是另一层间接,但由于您无法更改遗留代码,因此它似乎是一个合理的层。
JMock together with JDave can mock final methods and classes, if you need to. Here
are instructions. That being said I would treat this legacy code (as others have suggested already) as an external dependency and build interfaces and mock those. It is another layer of indirection, but since you can't change that legacy code, it seems to be a reasonable one.