Mockito&PowerMockito实战

本文包含了一些我个人认为使用Mockito和PowerMockito可能碰到的问题的解决方法(以下所有代码的运行前提是你已经配置好Mockito,PowerMockito的jar包)

------------------------------------------------------------------------------------------------------------------------------------------------------------------

package com.ray.mockito_demo1.present;
import static org.mockito.Mockito.*;
import java.util.Iterator;
import java.util.List;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.runners.MockitoJUnitRunner;
import com.ray.entity.Goods;
@RunWith(MockitoJUnitRunner.class)
public class MockitoTest {
/**
* 初始测试数据
*/
@Before
public void setUp() {
// 初始化mock测试数据
g1 = mock(Goods.class);
list = mock(List.class);
when(g1.getName()).thenReturn("iPhone10s plus");
when(list.size()).thenReturn(1);
when(list.get(0)).thenReturn(g1);
}


/**
* 测试 List.class
*/
@Test
public void testList() {
// execute 执行测试方法
int size = list.size();
for (int i = 0; i < size; i++)
System.out.println("goods name=" + list.get(i).getName());

// verify 验证期望调用的方法, verify(mock)方法的参数必须是Mock对象,
// 当参数只有一个的时候, 等价于verify(mock, times(1)), 没有设置第二个参数
// 的时候默认调用一次; verify(mock, never()), 验证方法是否没有调用过

verify(list).size(); // 验证goodsList.size()调用了一次
verify(list).get(0); // 验证goodsList.get(0)调用了一次
verify(g1).getName();// 验证goods1. getName ()没有调用过
}

/**
* 增强型for循环
* 因为增强型for循环会调用Iterator的hasNext(), next()方法,
* 所以我们需要mock一个Iterator, 并为这两个方法的调用做预设; 
* 如果不设置Iterator的话, 会得到一个NullPointerException;
*/

@Test
public void testAdvancedForLoop() {
Iterator itr = mock(Iterator.class);
when(list.iterator()).thenReturn(itr);

// 第一次调用返回true,第二次调用返回false, 因为集合里面只有一个Goods;
// 如果不设置thenReturn(false)的话将会产生死循环

when(itr.hasNext()).thenReturn(true).thenReturn(false);
when(itr.next()).thenReturn(g1);

// 执行测试
for(Goods g : list)
System.out.println("Congratrulations! you get one [" + g.getName() + "].");

//verify
verify(list).iterator();
verify(itr, times(2)).hasNext();
verify(g1).getName();
}

private Goods g1;
private List list;
}

------------------------------------------------------------------------------------------------------------------------------------------------------------------

package com.ray.mockito_demo1.present;

import static org.junit.Assert.*;
import static org.mockito.Mockito.*;
import org.powermock.api.mockito.PowerMockito;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.junit4.PowerMockRunner;

/**
 * PowerMockito模拟private, static, 构造方法
 * 
 * PowerMockito.verifyPrivate(...) 验证私有方法的调用
 * PowerMockito.mockStatic(...) 模拟静态方法

 * 
 * @author ray.sun
 */
@RunWith(PowerMockRunner.class)
/* 声明需要模拟的类 */
@PrepareForTest(OutMan.class)
public class PowerMockitoTest {
/**
* 模拟私有(private)方法
* @throws Exception
*/
@Test
public void testPrivateMethod() throws Exception {
PowerMockito.doReturn(10).when(oman, "charge", anyInt());

assertEquals(10, oman.fightTime(999));
PowerMockito.verifyPrivate(oman, times(1)).invoke("charge", 999);
}

/**
* 模拟静态(static)方法
*/
@Test
public void testStaticMethod(){
PowerMockito.mockStatic(OutMan.class);

when(OutMan.sleepTime()).thenReturn(0);
assertEquals(0, OutMan.sleepTime());
}

/**
* 模拟构造器
* @throws Exception 
*/
@Test
public void testConstructor() throws Exception{
oman = mock(OutMan.class);

//stub
PowerMockito.whenNew(OutMan.class).withNoArguments().thenReturn(oman);
PowerMockito.whenNew(OutMan.class).withArguments(anyDouble(), anyDouble()).thenReturn(oman);

//verify
assertEquals(oman, new OutMan());
assertEquals(oman, new OutMan(20, 50));
}

private OutMan oman = PowerMockito.spy(new OutMan());
}
class OutMan {
public OutMan() {}

public OutMan(double height, double weight) {
this.height = height;
this.weight = weight;
}

public static int sleepTime(){
return 8;
}

public int fightTime(int chargeTime){
return charge(chargeTime);
}

/**
* return the time that outman can fight
*/
private int charge(int chargeTime) {
if (0 == chargeTime)
return 1;
return chargeTime * 1000;
}

private double height;
private double weight;
}

------------------------------------------------------------------------------------------------------------------------------------------------------------------

package com.ray.mockito_demo1.present;
import static org.mockito.Mockito.*;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.powermock.api.mockito.PowerMockito;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.junit4.PowerMockRunner;
import com.ray.mockito_demo1.present.TaskList.Callback;

@RunWith(PowerMockRunner.class)
/* 声明需要模拟的类*/
@PrepareForTest(fullyQualifiedNames="com.ray.mockito_demo1.present.MySchedule*")
public class PowerMockitoTest2 {
@InjectMocks
private MySchedule mySchedule;

@Mock
private TaskList taskList;
@Mock
private Task1 task1;

/**
* 在匿名内部类里面模拟构造器
* @throws Exception
*/
@Test
public void testConstructOfAnoymousInnerClass() throws Exception{

PowerMockito.whenNew(Task1.class).withNoArguments().thenReturn(task1);

doCallRealMethod().when(taskList).handle(any(TaskList.Callback.class));

mySchedule.process();

verify(task1).execute();

}

}


class MySchedule {

public void process(){

new TaskList().handle(new Callback(){

public void execute() {

new Task1().execute();

}});

}

}

class TaskList {

void handle(Callback callback){

callback.execute();

};

public static interface Callback {

        public void execute();

    }}


class Task1{

public void execute(){

System.out.println("Task1 completed.");

}}

----------------------------------------------------------------------Goods.java----------------------------------------------------------------------------

package com.ray.entity;

public class Goods {

public String getName() {

return name;

}

public void setName(String name) {

this.name = name;

}

private String name;

}

-----------------------------------------------------------------------pom.xml------------------------------------------------------------------------------

xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
4.0.0

com.ray.demo
mockito-demo1
0.0.1-SNAPSHOT
jar

mockito-demo1
http://maven.apache.org



UTF-8

1.9.5

1.5.5



org.mockito

mockito-all

${mockito.version}

test

org.powermock

powermock-module-junit4

${powermock.version}

org.powermock

powermock-api-mockito

${powermock.version}


你可能感兴趣的:(Mockito&PowerMockito实战)