PowerMockito实践

概述:

PowerMockito擅长mock静态类/静态方法/私有方法/构造器


1. 当给spy的类设桩时,最好使用doReturn / doThrow / doNothing(只适应于返回void的方法)等,使用thenReturn/thenThrow可能会产生一些错误,

参考示例代码:testStub4SpyClass;

2. 当给静态方法设桩时,使用thenReturn/ thenThrow, 参考示例代码:verifyStaticMethod1;

3. 如果想验证测试类的private方法, 需要spy测试类,示例代码参考:verifyPrivateMethod;

4. Mockito&PowerMockito无法mock final类和方法;

5. 当使用PowerMockito时, 如果when在末尾, 方法的参数必须是实例,不能是方法调用(如method1(), 当用方法调用时,

mockito会认为是开始stub),当是方法调用的时候会报错:Unfinished-StubbingException; when在thenReturn前没有问题, 

参考代码:verifyTheStubbingOfWhen;

6. 如果想验证构造器,必须在方法执行前为类声明whenNew, 参考代码:verifyConstructor;

7. @PrepareForTest()的参数为Class[], 或String[], 例如:@PreapareForTest(fullyQualifiedNames={"xxx", "xxxxx"}, 源码如下:

public @interface PrepareForTest
{
  public abstract Class[] value();
  public abstract String[] fullyQualifiedNames();
}


示例代码:

package com.ray.mockito_demo1;

import static org.mockito.Mockito.*;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.InjectMocks;
import org.powermock.api.mockito.PowerMockito;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.junit4.PowerMockRunner;

@RunWith(PowerMockRunner.class)
// 声明需要测试静态方法/私有方法的类, 可以声明多个,用逗号隔开
@PrepareForTest({ ClassA.class })
public class PowerMockitoDemo3 {

	// /$ begin test ClassA
	@InjectMocks
	private ClassA classA;

	@Test
	public void testStub4SpyClass() throws Exception {
		classA = PowerMockito.spy(classA);
		String task = "跑步";
		// PowerMockito.when(classA, "method2", task).thenReturn("。。。。");
		PowerMockito.doReturn("。。。。").when(classA, "method2", task);

		classA.invokeMethod2(task);
		PowerMockito.verifyPrivate(classA).invoke("method2", task);
	}

	@Test
	public void verifyTheStubbingOfWhen() throws Exception {

		User u1 = mock(User.class);
		when(u1.getName()).thenReturn("张三");

		classA = PowerMockito.spy(classA);
		// 抛出异常UnfinishedStubbingException
		PowerMockito.doReturn("。。。。").when(classA, "method2", u1.getName());
		//正确的方式
		// PowerMockito.doReturn("。。。。").when(classA, "method2", "张三");
		//或者 PowerMockito.when(classA, "method2", u1.getName()).thenReturn("。。。。");
		
		classA.invokeMethod2(u1.getName());
		PowerMockito.verifyPrivate(classA).invoke("method2", u1.getName());
	}

	@Test
	public void verifyStaticMethod1() throws Exception {
		PowerMockito.mockStatic(ClassA.class);
		PowerMockito.spy(ClassA.class);
		PowerMockito.doReturn("hahaha").when(ClassA.class, "staticMethod1");

		ClassA.invokeStaticMethod1();
		PowerMockito.verifyStatic();
		ClassA.staticMethod1();
	}

	@Test
	public void verifyPrivateMethod() throws Exception {
		// 如果不将PowerMockito.spy(classA)赋值给classA, mock将不会生效
		classA = PowerMockito.spy(classA);
		classA.invokeMethod1();
		PowerMockito.verifyPrivate(classA).invoke("method1");
	}
	
	@Test
	public void verifyConstructor() throws Exception{
		User u1 = mock(User.class);
		when(u1.getName()).thenReturn("李四");
		
		//如果没有设置whenNew, 将会报错IllegalStateException... 
		//Note that only expected object creations(e.g. those using whenNew(..)) can be verified
		PowerMockito.whenNew(User.class).withNoArguments().thenReturn(u1);
		
		classA.invokeMethod3();
		PowerMockito.verifyNew(User.class).withNoArguments();		
	}	
}

class ClassA {
	public static void invokeStaticMethod1() {
		System.out.println(staticMethod1());
	}

	public static String staticMethod1() {
		return "test static method1.";
	}

	public void invokeMethod1() {
		method1();
	}

	public void invokeMethod2(String param) {
		System.out.println(method2(param));
	}
	
	public void invokeMethod3(){
		User user = new User();
		user.setName("张三");
		method3(user);
	}
	
	private void method3(User user){
		System.out.println(String.format("Welcome, %s", user.getName()));
	}

	private void method1() {
		System.out.println("method1 executed.");
	}

	private String method2(String task) {
		return String.format("%s executed.", task);
	}
}

class User {
	private String name;

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

}


相关jar包:

mvn仓库:http://mvnrepository.com/


		
			org.mockito
			mockito-all
			1.9.5
			test
		

		
			org.powermock
			powermock-module-junit4
			1.5.5
		

		
			org.powermock
			powermock-api-mockito
			1.5.5
		
	


你可能感兴趣的:(java)