PowerMock单元测试

发表于:2018-9-18 10:50

字体: | 上一篇 | 下一篇 | 我要投稿

 作者:HappyCowboy    来源:博客园

  在Java程序的单元测试中常用的mock工具有Mockito和EasyMock。但是这两种mock工具都无法实现对静态、final、私有方法或类的mock。因此有了功能强大的PowerMock工具。PowerMock并不是一个独立、全新的工具而是在Mockito和EasyMock的基础上进行的扩展,它分别有针对Mockito级EasyMock的扩展实现。本文主要介绍PowerMock的常见用法:
  1.pom依赖
  <dependency>
  <groupId>junit</groupId>
  <artifactId>junit</artifactId>
  <version>4.10<version>
  <scope>test</scope>
  </dependency>
  <dependency>
  <groupId>org.powermock</groupId>
  <artifactId>powermock-module-junit4</artifactId>
  <version>1.6.3</version>
  <scope>test</scope>
  </dependency>
  <dependency>
  <groupId>org.powermock</groupId>
  <artifactId>powermock-api-mockito</artifactId>
  <version>1.6.3</version>
  <scope>test</scope>
  </dependency>

  2.基本用法
  2.1 测试类加上必要的注解
  @RunWith(PowerMockRunner.class)
  @PrepareForTest({ExtensionLoader.class,Configs.class})  //静态类,测试类本身(需要mock构造方法时)
  @PowerMockIgnore("javax.management.*")

  2.2 mock基本对象
  测试 convert.convertAndHanlder(method,ref,bead)方法
  @Mock
  Convert convert;
  when(convert.convertAndHanlder(eq(method),eq(ref),eq(bead))).thenReturn(bead);

  2.3 mock无返回值的方法
  @Mock
  ProviderComposeConfig providerComposeConfig;
  doNothing().when(providerComposeConfig).putSync(eq(providerConfig));

  2.4 mock方法执行异常场景
  @Mock
  ProviderComposeConfig providerComposeConfig;
  doThrow(new Exception("执行失败")).when(providerComposeConfig).putSync(eq(providerConfig));

  2.5 mock 静态方法
  测试Configs.getConfig(ProviderComposeConfig.class)方法
  前提:@PrepareForTest注解中添加该类:ProviderComposeConfig.class
  @Mock
  ProviderComposeConfig configs;
  PowerMockito.mockStatic(Configs.class);
  when(Configs.getConfig(eq(ProviderComposeConfig.class))).thenReturn(configs);
  mock无返回值的static方法
  // "xxxUtil" 是类名
  // "xxxStaticMethod" 是 static 方法的方法名
  // 这里假设 "xxxStaticMethod" 需要两个参数,一个是 int 型,一个是 String 型
  PowerMockito.doNothing().when(xxxUtil.class, "xxxStaticMethod", 1,"mysql");
  mock可变参数传递
  public class Demo {
  public static void test(String... args) {
  System.out.println(args);
  }
  }

  测试方法:
  @RunWith(PowerMockRunner.class)
  @PrepareForTest({Demo.class})
  @PowerMockIgnore("javax.management.*")
  public class DemoTest {
  @Test
  public void test() throws Exception {
  PowerMockito.mockStatic(Demo.class);
  PowerMockito.doNothing().when(Demo.class,"test",eq("liu1"),eq("liu2"));
  Demo.test("liu1","liu2");
  }
  }

  2.6 mock 构造方法
  前提:@PrepareForTest注解中添加该类:HookContext.class
  @Mock
  HookContext context;
  //无参构造
  PowerMockito.whenNew(HookContext.class).withNoArguments().thenReturn(context);
  //有参构造
  PowerMockito.whenNew(HookContext.class).withArguments(anystring()).thenReturn(context);
  ③完成实例
  被测试类:
  public class HandlerHook {
  public final static String id = "handler";
  @Override
  public Bead doCall(HookContext context, Bead bead, AccessId id) throws Throwable {
  ProviderComposeConfig configs = Configs.getConfig(ProviderComposeConfig.class);
  ProviderConfig config = configs == null ? null : configs.get(id);
  if (config == null) {
  // 即没有该服务,1.本地调用 2.客户端信息有误,访问IP:PORT 却没有服务
  return null;
  }
  // 拿到转换器,调用
  Convert convert = ExtensionLoader.getExtensionLoader(Convert.class).getExtensionById(ConvertProcessor.id);
  return convert.convertAndHanlder(config.getMethod(), config.getRef(), bead);
  }
  }

  测试类:
  @RunWith(PowerMockRunner.class)
  @PrepareForTest({ExtensionLoader.class,Configs.class})
  @PowerMockIgnore("javax.management.*")
  public class HandlerHookTest {
  @Mock
  HookContext hookContext;
  @Mock
  Bead bead;
  @Mock
  AccessId accessId;
  @Mock
  ExtensionLoader<Convert> extensionLoader;
  @Mock
  ProviderComposeConfig configs;
  @Mock
  ProviderConfig config;
  @Mock
  Method method ;
  @Mock
  Object ref;
  @Mock
  Convert convert;
  private HandlerHook handlerHook = new HandlerHook();
  @Test
  public void doCall() throws Throwable {
  PowerMockito.mockStatic(Configs.class);
  when(Configs.getConfig(eq(ProviderComposeConfig.class))).thenReturn(configs);
  when(configs.get(eq(accessId))).thenReturn(config);
  PowerMockito.mockStatic(ExtensionLoader.class);
  when(ExtensionLoader.getExtensionLoader(eq(Convert.class))).thenReturn(extensionLoader);
  when(extensionLoader.getExtensionById(eq("map"))).thenReturn(convert);
  when(config.getMethod()).thenReturn(method);
  when(config.getRef()).thenReturn(ref);
  when(convert.convertAndHanlder(eq(method),eq(ref),eq(bead))).thenReturn(bead);
  assertEquals(bead, handlerHook.doCall(hookContext, bead, accessId));
  }
  }

   上文内容不用于商业目的,如涉及知识产权问题,请权利人联系博为峰小编(021-64471599-8017),我们将立即处理。
《2023软件测试行业现状调查报告》独家发布~

关注51Testing

联系我们

快捷面板 站点地图 联系我们 广告服务 关于我们 站长统计 发展历程

法律顾问:上海兰迪律师事务所 项棋律师
版权所有 上海博为峰软件技术股份有限公司 Copyright©51testing.com 2003-2024
投诉及意见反馈:webmaster@51testing.com; 业务联系:service@51testing.com 021-64471599-8017

沪ICP备05003035号

沪公网安备 31010102002173号