Mockito学习总结

转载自:http://blog.csdn.net/jinnchang/article/details/8814720

1、简介

       所谓的mock,就是指,如果我们写的代码依赖于某些对象,而这些对象又很难手动创建,那么就使用一个虚拟的对象来测试。Mockito是目前java中使用比较流行的mock工具。它使用起来简单,学习成本很低,而且具有非常简洁的Api,测试代码的可读性很高。因此它十分受欢迎,用户群越来越多,很多的开源的软件也选择了Mockito。

如果项目是通过Maven管理的,需要在项目的pom.xml中增加如下的依赖:


<dependency>
	<groupId>org.mockito</groupId>
	<artifactId>mockito-core</artifactId>
	<version>1.9.0</version>
	<scope>test</scope>
</dependency>

2、展示一个简单完整的mockito应用实例

/**
 * Description:被测试类
 * UserService.java Create on 2013-4-17 下午4:47:17 
 * @author 张景
 * @version 2.0
 * Copyright (c) 2013 telek. All Rights Reserved.
 */
public class UserService {

	private UserDao userDao;

	public String getName(String userId) {
		return userDao.getName(userId);
	}

	public UserDao getUserDao() {
		return userDao;
	}

	public void setUserDao(UserDao userDao) {
		this.userDao = userDao;
	}

}

/**
 * Description:对应的测试类
 * UserServiceTest.java Create on 2013-4-17 下午4:48:34 
 * @author 张景
 * @version 2.0
 * Copyright (c) 2013 telek. All Rights Reserved.
 */
public class UserServiceTest {

	@Test
	public void testGetName() {
		//创建Mock对象
		UserDao userDao = Mockito.mock(UserDao.class);
		
		//设置方法调用的预期返回
		Mockito.when(userDao.getName("Tom")).thenReturn("Hello Tom");
		
		//验证方法调用结果
		UserService userService = new UserService();
		userService.setUserDao(userDao);
		String result = userService.getName("Tom");
		assertEquals("Hello Tom", result);
		
		//验证方法调用过程
		Mockito.verify(userDao,Mockito.times(1)).getName("Tom");
	}

}

3、了解Stub和Mock

在开始使用Mockito之前,先简单的了解一下Stub和Mock的区别:Stub对象用来提供测试时所需要的测试数据,可以对各种交互设置相应的回应。例如我们可以设置方法调用的返回值等等。Mockito中when(mock).thenReturn(value)这样的语法便是设置方法调用的返回值。另外也可以设置方法在何时调用会抛异常等。Mock对象用来验证测试中所依赖对象间的交互是否能够达到预期。Mockito中用verify(mock).someMethod()语法来验证someMethod方法是否按照预期进行了调用。

4、Mockito运行过程

A、Mock对象的创建

创建Mock对象的语法为:
mock(Class<T> classToMock) 
mock(Class<T> classToMock, String name) 
可以对类和接口进行mock对象的创建,创建的时候可以为mock对象命名,也可以忽略命名参数。为mock对象命名的好处就是调试的时候会很方便,比如,我们mock多个对象,在测试失败的信息中会把有问题的mock对象打印出来,有了名字我们可以很容易定位和辨认出是哪个mock对象出现的问题。另外它也有限制,对于final类、匿名类和Java的基本类型是无法进行mock的。 

B、Mock对象的期望行为及返回值设定

通过when(mock.someMethod()).thenReturn(value) 来设定mock对象某个方法调用时的返回值。(注意:Mockito对于static和final修饰的方法是无法进行设定的。)
a、对方法设定返回值:
方式1:when(mock.someMethod()).thenReturn(value);
方式2:doReturn((value)).when(mock).someMethod();

b、对方法设定返回异常
方式1:when(mock.someMethod()).thenThrow(new Exception());
方式2:doThrow(new Exception()).when(mock).someMethod();

c、对迭代风格设定返回值
方式1:when(mock.someMethod()).thenReturn(value1).thenReturn(value2);
方式2:when(mock.someMethod()).thenReturn(value1,value2);

d、对void方法进行方法预期设定
doNothing().when(mock).someMethod();

C、Mock对象的行为验证

mock对象一旦建立便会自动记录自己的交互行为,所以我们可以有选择的对它的交互行为进行验证。在Mockito中验证mock对象交互行为的方法是:verify(mock).someMethod()。
a、验证的基本方法:verify(mock).someMethod();
b、验证未曾执行的方法:verify(mock,never()).someMethod();
c、查询多余的方法调用:verifyNoMoreInteractions(mock);
verifyNoMoreInteractions()方法可以传入多个mock对象作为参数,用来验证传入的这些mock对象是否存在没有验证过的调用方法。
d、查询没有交互的mock对象
verifyZeroInteractions()也是一个测试工具,源码和verifyNoMoreInteractions()的实现是一样的,为了提高逻辑的可读性,所以只不过名字不同。
e、验证方法调用的次数:verify(mock,times(n));
如果要验证Mock对象的某个方法调用次数,则需给verify方法传入相关的验证参数,它的调用接口是verify(T mock,VerificationMode mode)。times(n)参数便是验证调用次数的参数,n代表方法调用次数。其实verify方法中如果不传调用次数的验证参数,它默认传入的便是times(1),即验证mock对象的方法是否只被调用一次,如果有多次调用测试方法将会失败。
Mockito除了提供times(n)方法供我们调用外,还提供了很多可选的方法: 
never() ----没有被调用,相当于times(0) 
atLeast(n) ----至少被调用n次 
atLeastOnce()   ----相当于atLeast(1) 
atMost(n) ----最多被调用n次
f、超时验证:verify(mock,timeout(millis)).someMethod();
Mockito提供对超时的验证,但是目前不支持在下面提到的顺序验证中使用。进行超时验证和上述的次数验证一样,也要在verify中进行参数的传入,参数为timeout(int millis),timeout方法中输入的是毫秒值。

D、mock对象的重置

Mockito提供了reset(mock)方法,用来重置mock对象。当mock对象被重置后,它将回到刚创建完的状态,没有任何stubbing和方法调用。这个特性平时是很少用到的,因为我们大都为每个test方法创建mock,所以没有必要对它进行重置。官方提供这个特性的唯一目的是使得我们能在有容器注入的mock对象中工作更为方便。所以,当决定要使用这个方法的时候,首先应该考虑一下我们的测试代码是否简洁和专注,测试方法是否已经超长了。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值