欢迎访问 生活随笔!

生活随笔

当前位置: 首页 > 编程资源 > 编程问答 >内容正文

编程问答

使用PowerMock模拟静态方法

发布时间:2023/12/3 编程问答 38 豆豆
生活随笔 收集整理的这篇文章主要介绍了 使用PowerMock模拟静态方法 小编觉得挺不错的,现在分享给大家,帮大家做个参考.
在最近的博客中,我试图强调使用依赖注入的好处,并表达一种想法,即这种技术的主要好处之一是,通过在类之间提供高度的隔离,它可以使您更轻松地测试代码,并且得出的结论是,许多好的测试等于好的代码。

但是,当您没有依赖项注入并且使用的第三方库包含某个包含静态方法的特定年份的类时,会发生什么? 一种方法是通过在它们周围编写包装器或适配器并在测试过程中提供隔离来隔离这些类。 但是,还有另一种方法:使用PowerMock。 PowerMock是一个模拟框架,可扩展其他模拟框架以提供急需的其他功能。 模仿旧广告:“它刷新了其他模拟框架无法达到的部分”。

该博客介绍了PowerMock模拟静态方法的能力,并提供了一个模拟JDK的ResourceBundle类的示例,众所周知,该类使用ResourceBundle.getBundle(...)来…加载资源束。

与许多其他博客作者和作家一样,我通常会提出一些高度人为的方案来突出问题。 今天有所不同,我只得到了一个使用ResourceBundle的类,称为:UsesResourceBundle:

public class UsesResourceBundle {private static Logger logger = LoggerFactory.getLogger(UsesResourceBundle.class);private ResourceBundle bundle;public String getResourceString(String key) {if (isNull(bundle)) {// Lazy load of the resource bundleLocale locale = getLocale();if (isNotNull(locale)) {this.bundle = ResourceBundle.getBundle("SomeBundleName", locale);} else {handleError();}}return bundle.getString(key);}private boolean isNull(Object obj) {return obj == null;}private Locale getLocale() {return Locale.ENGLISH;}private boolean isNotNull(Object obj) {return obj != null;}private void handleError() {String msg = "Failed to retrieve the locale for this page";logger.error(msg);throw new RuntimeException(msg);} }

您可以看到有一个方法:getResourceString(…),给定一个键将从包中检索资源字符串。 为了使这项工作更有效率,我懒洋洋地加载了我的资源包,加载后,我调用bundle.getString(key)检索我的资源。 为了测试这一点,我编写了一个PowerMock JUnit测试:

import static org.easymock.EasyMock.expect; import static org.junit.Assert.assertEquals; import static org.powermock.api.easymock.PowerMock.mockStatic; import static org.powermock.api.easymock.PowerMock.replayAll; import static org.powermock.api.easymock.PowerMock.verifyAll;import java.util.Locale; import java.util.MissingResourceException; import java.util.ResourceBundle;import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.powermock.api.easymock.annotation.Mock; import org.powermock.core.classloader.annotations.PrepareForTest; import org.powermock.modules.junit4.PowerMockRunner;@RunWith(PowerMockRunner.class) @PrepareForTest(UsesResourceBundle.class) public class UsesResourceBundleTest {@Mockprivate ResourceBundle bundle;private UsesResourceBundle instance;@Beforepublic void setUp() {instance = new UsesResourceBundle();}@Testpublic final void testGetResourceStringAndSucceed() {mockStatic(ResourceBundle.class);expect(ResourceBundle.getBundle("SomeBundleName", Locale.ENGLISH)).andReturn(bundle);final String key = "DUMMY";final String message = "This is a Message";expect(bundle.getString(key)).andReturn(message);replayAll();String result = instance.getResourceString(key);verifyAll();assertEquals(message, result);}@Test(expected = MissingResourceException.class)public final void testGetResourceStringWithStringMissing() {mockStatic(ResourceBundle.class);expect(ResourceBundle.getBundle("SomeBundleName", Locale.ENGLISH)).andReturn(bundle);final String key = "DUMMY";Exception e = new MissingResourceException(key, key, key);expect(bundle.getString(key)).andThrow(e);replayAll();instance.getResourceString(key);}@Test(expected = MissingResourceException.class)public final void testGetResourceStringWithBundleMissing() {mockStatic(ResourceBundle.class);final String key = "DUMMY";Exception e = new MissingResourceException(key, key, key);expect(ResourceBundle.getBundle("SomeBundleName", Locale.ENGLISH)).andThrow(e);replayAll();instance.getResourceString(key);}}

在上面的代码中,我采取了不寻常的步骤,包括导入语句。 要强调的是,我们使用的是PowerMock的导入静态版本,而不是EasyMock的静态版本。 如果您不小心导入了EasyMock的静态函数,那么整个过程将不起作用。

设置模拟静态调用的测试有四个简单的步骤:

1.使用PowerMock JUnit运行器:

@RunWith(PowerMockRunner.class)

2.声明我们要嘲笑的测试类:

@PrepareForTest(UsesResourceBundle.class)

3.告诉PowerMock包含静态方法的类的名称:

mockStatic(ResourceBundle.class);

4.设置期望值,告诉PowerMock期望对静态方法的调用:

expect(ResourceBundle.getBundle("SomeBundleName", Locale.ENGLISH)).andReturn(bundle);

其余的工作很顺利,您可以为其他标准方法调用设置期望,并告诉PowerMock / EasyMock运行测试,并验证结果:

final String key = "DUMMY"; final String message = "This is a Message"; expect(bundle.getString(key)).andReturn(message);replayAll(); String result = instance.getResourceString(key); verifyAll();

PowerMock可以做更多的事情,例如模拟构造函数和私有方法调用。 也许以后再说……

参考: 使用PowerMock来模拟我们JCG合作伙伴的 静态方法 调试队长博客上的 Roger。

相关文章 :
  • JUnit 4.9(测试版3)中的规则
  • 使用PowerMock测试对象的内部状态
  • Servlet 3.0异步处理可将服务器吞吐量提高十倍
  • 用Scala测试
  • Java工具:源代码优化和分析
  • Java教程和Android教程列表

翻译自: https://www.javacodegeeks.com/2011/11/mock-static-methods-with-powermock.html

总结

以上是生活随笔为你收集整理的使用PowerMock模拟静态方法的全部内容,希望文章能够帮你解决所遇到的问题。

如果觉得生活随笔网站内容还不错,欢迎将生活随笔推荐给好友。