Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
powermock example
package demo.powermock;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.powermock.api.mockito.PowerMockito;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.junit4.PowerMockRunner;
import static org.junit.Assert.*;
@RunWith(PowerMockRunner.class)
@PrepareForTest(XxxService.class) //注意:非 XxxUtil.class
public class MockConstructionTest {
/*
* 1.Use the @RunWith(PowerMockRunner.class) annotation at the class-level of the test case.
* 2.Use the @PrepareForTest(ClassThatCreatesTheNewInstance.class) annotation at the class-level of the test case.
* 3.PowerMockito.whenNew(MockNewClass.class)
* 4.Note : withArguments(value), value必须与实际new时的参数类型相同
*/
@Test
public void mockConstruction() throws Exception {
//prepare
XxxService service = new XxxService();
XxxUtil util = new XxxUtil();
String name = "hello";
util.setName(name);
PowerMockito.whenNew(XxxUtil.class).withNoArguments().thenReturn(util);
//action
XxxUtil res = service.getUtil();
//assert
assertEquals(name, res.getName());
}
}
package demo.powermock;
/**
* 请大家自己测试
* @author bohan.sj
*/
public class MockFinalMethodOrClassTest {
}
package demo.powermock;
import static org.mockito.Matchers.anyLong;
import static org.mockito.Mockito.*;
import java.io.File;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.powermock.api.mockito.PowerMockito;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.junit4.PowerMockRunner;
@RunWith(PowerMockRunner.class)
@PrepareForTest(XxxUtil.class) // 注意:非 Thread.class
public class MockJavaCoreLibraryTest {
@Test
public void mockJavaCoreLibrary() throws Exception {
//prepare
PowerMockito.mockStatic(Thread.class);
//action
XxxUtil.sleep(1000);
//assert
PowerMockito.verifyStatic(times(1));
Thread.sleep(anyLong());
}
/**
* 关键点:withArguments(value), value必须与实际new时的参数相同
* @throws Exception
*/
@Test
public void readFile$mockNewFile() throws Exception {
//preapare
File file = mock(File.class);
PowerMockito.whenNew(File.class).withArguments(anyString()).thenReturn(file);
//action
XxxUtil.readFile(anyString());
//assert
verify(file, times(1)).getAbsolutePath();
}
}
package demo.powermock;
import static org.junit.Assert.assertFalse;
import static org.mockito.Matchers.anyInt;
import static org.mockito.Mockito.times;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.powermock.api.mockito.PowerMockito;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.junit4.PowerMockRunner;
// We prepare XxxServiceClass for test because it's final or we need to mock private or static methods
@RunWith(PowerMockRunner.class)
@PrepareForTest(XxxService.class) // spy是不需要声明 @PrepareForTest,但必须使用 doReturn("foo").when(spy).get(0);
public class MockPartialMethodTest {
private XxxService service = new XxxService();
@Test
public void mockPartialPrivateMethod() throws Exception {
//prepare
service = PowerMockito.spy(service);
PowerMockito.doReturn(false).when(service, "isNeedHandle", anyInt()); // mock private method
/*
* spy must use doReturn()
*
List list = new LinkedList();
List spy = spy(list);
//Impossible: real method is called so spy.get(0) throws IndexOutOfBoundsException (the list is yet empty)
when(spy.get(0)).thenReturn("foo");
//You have to use doReturn() for stubbing
doReturn("foo").when(spy).get(0);
*/
//action
boolean res = service.handle(2);
//assert
assertFalse(res);
PowerMockito.verifyPrivate(service, times(1)).invoke("isNeedHandle", anyInt());
}
}
package demo.powermock;
import static org.junit.Assert.assertFalse;
import static org.mockito.Matchers.anyInt;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.when;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.powermock.api.mockito.PowerMockito;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.junit4.PowerMockRunner;
@RunWith(PowerMockRunner.class)
@PrepareForTest(XxxUtil.class)
public class MockStaticMethodTest {
@Test
public void mockStaticMethodAndVerifyStaticMethod() {
//prepare
XxxService service = new XxxService();
PowerMockito.mockStatic(XxxUtil.class);
when(XxxUtil.isSafe(anyInt())).thenReturn(false);
//action
boolean res = service.isAllowBuy(2);
//assert
assertFalse(res);
/*
* 提示:静态方法verify有点别扭,如下是官方示例
*
// Different from Mockito, always use PowerMockito.verifyStatic() first
PowerMockito.verifyStatic(Mockito.times(2));
// Use EasyMock-like verification semantic per static method invocation
Static.firstStaticMethod(param);
// Remember to call verifyStatic() again
PowerMockito.verifyStatic(Mockito.never());
Static.secondStaticMethod();
*/
PowerMockito.verifyStatic(times(1));
XxxUtil.isSafe(anyInt());
}
@Test(expected=RuntimeException.class)
public void mockStaticMethodThrowException() {
//prepare
XxxService service = new XxxService();
PowerMockito.mockStatic(XxxUtil.class);
PowerMockito.doThrow(new RuntimeException()).when(XxxUtil.isSafe(anyInt()));
//action
service.isAllowBuy(2);
}
}
package demo.powermock;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import static org.mockito.Matchers.anyInt;
import static org.mockito.Mockito.times;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import org.junit.Before;
import org.junit.Test;
import org.powermock.api.mockito.PowerMockito;
/**
* 注:当然可用反射实现同样目的,可认为powermock帮你提供工具类
* @author bohan.sj
*/
public class PrivateFieldOrMethodTest {
private XxxService target;
@Before
public void setUp() {
target = new XxxService();
}
@Test
public void modifyPrivateField() throws Exception {
//prepare
Field f = PowerMockito.field(XxxService.class, "threshold");
f.set(null, 10);
//action
int result = target.sum();
//assert
assertEquals(10, result);
}
@Test
public void testPrivateMethod() throws Exception {
//preapre
Method m = PowerMockito.method(XxxService.class, "isPositiveNumber", new Class[]{int.class});
//action
boolean res = (Boolean)m.invoke(target, 2);
//assert
assertTrue(res);
}
@Test
public void verifyPrivateMethodInvoke() throws Exception {
//prepare
//action
target.foreach(2);
//assert
PowerMockito.verifyPrivate(target, times(2)).invoke("isPositiveNumber", anyInt());
}
}
package demo.powermock;
public class XxxService {
/*
* 1.修改私有域
* - unit test 必须保证 '快',需要修改private field
*/
private static int threshold = 1000000;
public int sum() {
int i=0;
while(i < threshold) {
i=i+1;
}
return i;
}
/*
* 2.测试私有方法
*/
private boolean isPositiveNumber(int i) {
if(i > 0) {
return true;
} else {
return false;
}
}
/*
* 3.无返回值,校验:对某方法调用次数
*/
public void foreach(int count) {
for(int i=0; i<count; i++) {
isPositiveNumber(i);
}
}
/*
* 3.mock静态方法
*/
public boolean isAllowBuy(int i) {
//判断是否安全
if(XxxUtil.isSafe(i)) {
//判断是否超过支付能力
// ....
}
return false;
}
/*
* 4.mock partial method
* - 需要mock isNeedHandle(),否则导致单元测试粒度太大
*/
public boolean handle(int i) {
if(isNeedHandle(i)) {
// ... logic handle
return true;
}
return false;
}
private boolean isNeedHandle(int i) {
//假设此方法逻辑,依赖外部服务、且逻辑较复杂
return true;
}
/*
* 5.mock construction
*/
public XxxUtil getUtil() {
XxxUtil util = new XxxUtil();
return util;
}
}
package demo.powermock;
import java.io.File;
public class XxxUtil {
public static boolean isSafe(int i) {
if(i > 0) {
return true;
} else {
return false;
}
}
private String name = "XxxUtil";
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
/*
* 1. mock java core library
* - 无结果返回,只能verify方法是否被调用
* - 且是Java自身类
*/
public static void sleep(long time) throws Exception {
Thread.sleep(time);
}
/*
* 2. mock java core library
* - new instance
*/
public static void readFile(String filename) throws Exception {
File file = new File(filename);
System.out.println(file.getAbsolutePath());
}
}
@sairam

This comment has been minimized.

Copy link

commented Sep 1, 2015

The static method at MockJavaCoreLibraryTest.java L21 is not mocking any method. How can we mock a static method?

@yanzhilong

This comment has been minimized.

Copy link

commented Jun 17, 2016

gradle 要怎么依赖?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.