模拟测试概述
目前支持Java语言的Mock测试工具有EasyMock、JMock、Mockito、MockCreator、Mockrunner、MockMaker等,Mockito是一个针对Java的Mocking框架。它与EasyMock和JMock很相似,是一套通过简单的方法对于指定的接口或类生成 Mock 对象的类库,避免了手工编写Mock对象。但Mockito是通过在执行后校验什么已经被调用,它消除了对期望行为(Expectations)的需要。使用Mockito,在准备阶段只需花费很少的时间,可以使用简洁的API编写出漂亮的测试,可以对具体的类创建Mock对象,并且有"监视"非Mock对象的能力。
Mockito使用起来简单,学习成本很低,而且具有非常简洁的API,测试代码的可读性很高,因此它十分受欢迎,用户群越来越多,很多开源软件也选择了Mockito。要想了解更多有关Mockito的信息,可以访问其官方网站http://www.mockito.org/。在开始使用Mockito之前,先简单了解一下Stub和Mock的区别。相比Easymock,JMock,编写出来的代码更加容易阅读。无须录制mock方法调用就返回默认值是一个很大优势。目前最新的版本是1.9.0。
Stub对象用来提供测试时所需要的测试数据,可以对各种交互设置相应的回应。例如我们可以设置方法调用的返回值等。Mockito中 when(…).thenReturn(…) 这样的语法便是设置方法调用的返回值。另外也可以设置方法在何时调用会抛出异常等。
Mock对象用来验证测试中所依赖对象间的交互是否能够达到预期。Mockito中用 verify(…).methodXxx(…) 语法来验证 methodXxx方法是否按照预期进行了调用。有关stub和mock的详细论述请见Martin Fowler的文章《Mocks Aren't Stub》,地址为http://martinfowler.com/articles/mocksArentStubs.html。在Mocking框架中所谓的Mock对象实际上是作为上述的Stub和Mock对象同时使用的。因为它既可以设置方法调用返回值,又可以验证方法的调用。
创建Mock对象
可以对类和接口进行Mock对象的创建,创建的时候可以为Mock对象命名,也可以忽略命名参数。为Mock对象命名的好处就是调试的时候会很方便。比如,我们Mock多个对象,在测试失败的信息中会把有问题的Mock对象打印出来,有了名字我们可以很容易定位和辨认出是哪个Mock对象出现的问题。另外它也有限制,对于final类、匿名类和Java的基本类型是无法进行Mock的。除了用Mock方法来创建模拟对象,如mock(Class<T> classToMock),也可以使用@mock注解定义Mock,下面我们通过实例来介绍一下如何创建一个Mock对象。代码清单16 8 MockitoSampleTest.java创建Mock对象
import org.junit.Test;
import org.mockito.Mock;
import com.baobaotao.domain.User;
import com.baobaotao.service.UserService;
import com.baobaotao.service.UserServiceImpl;
import static org.junit.Assert.*;
import static org.mockito.Mockito.*;
import org.mockito.MockitoAnnotations;
public class MockitoSampleTest{
//① 对接口进行模拟
UserService mockmockUserService = mock(UserService.class);
//② 对类进行模拟
UserServiceImpl mockmockServiceImpl = mock(UserServiceImpl.class);
//③ 基于注解模拟类
@Mock
User mockUser;
@Before
public void initMocks() {
//④ 初始化当前测试类所有@Mock注解模拟对象
MockitoAnnotations.initMocks(this);
}
}
在①处和②处,通过Mockito提供的mock()方法创建UserService 用户服务接口、用户服务实现类UserServiceImpl的模拟对象。在③处,通过@Mock注解创建用户User类模拟对象,并需要在测试类初始化方法中,通过MockitoAnnotations.initMocks()方法初始化当前测试类中所有打上@Mock注解的模拟对象。如果没有执行这一步初始化动作,测试时会报模拟对象为空对象异常
设定Mock对象的期望行为及返回值
从上文中我们已经知道可以通过when(mock.someMethod()).thenReturn(value)来设定Mock对象的某个方法调用时的返回值,但它也同样有限制条件:对于static和final修饰的方法是无法进行设定的。下面我们通过实例来介绍一下如何调用方法及设定返回值。
代码清单16 9 MockitoSampleTest.java设定模拟对象的行为及返回值
import org.junit.Test;
import org.mockito.Mock;
import com.baobaotao.domain.User;
import com.baobaotao.service.UserService;
import com.baobaotao.service.UserServiceImpl;
public class MockitoSampleTest {
//① 模拟接口UserService测试
@Test
public void testMockInterface() {
//①-1 对方法设定返回值
when(mockUserService.findUserByUserName("tom")).thenReturn(
new User("tom", "1234"));
//①-2 对方法设定返回值
doReturn(true).when(mockServiceImpl).hasMatchUser("tom", "1234");
//①-3 对void方法进行方法预期设定
User u = new User("John", "1234");
doNothing().when(mockUserService).registerUser(u);
//①-4 执行方法调用
User user = mockUserService.findUserByUserName("tom");
boolean isMatch = mockUserService.hasMatchUser("tom","1234");
mockUserService.registerUser(u);
assertNotNull(user);
assertEquals(user.getUserName(), "tom");
assertEquals(isMatch, true);
}
//② 模拟实现类UserServiceImpl测试
@Test
public void testMockClass() {
// 对方法设定返回值
when(mockServiceImpl.findUserByUserName("tom"))
.thenReturn(new User("tom", "1234"));
doReturn(true).when(mockServiceImpl).hasMatchUser("tom", "1234");
User user = mockServiceImpl.findUserByUserName("tom");
boolean isMatch = mockServiceImpl.hasMatchUser("tom","1234");
assertNotNull(user);
assertEquals(user.getUserName(), "tom");
assertEquals(isMatch, true);
}
//③ 模拟User类测试
@Test
public void testMockUser() {
when(mockUser.getUserId()).thenReturn(1);
when(mockUser.getUserName()).thenReturn("tom");
assertEquals(mockUser.getUserId(),1);
assertEquals(mockUser.getUserName(), "tom");
}
…在①处,模拟测试接口UserService的findUserByUserName()方法、hasMatchUser()方法及registerUser()方法。在①-1处通过when().thenReturn()语法,模拟方法调用及设置方法的返回值,实例通过模拟调用UserService 用户服务接口的查找用户findUserByUserName()方法,查询用户名为"tom"详细的信息,并设置返回User对象:new User("tom", "1234")。在①-2处通过doReturn (). when ()语法,模拟判断用户hasMatchUser()方法的调用,判断用户名为"tom"及密码为"1234"的用户存在,并设置返回值为:true。在①-3处对void方法进行方法预期设定,如实例中调用注册用户registerUser()方法。设定调用方法及返回值之后,就可以执行接口方法调用验证。在②处和③处,模拟测试用户服务实现类UserServiceImpl,测试的方法与模拟接口一致。
验证交互行为
Mock对象一旦建立便会自动记录自己的交互行为,所以我们可以有选择地对其交互行为进行验证。在Mockito中验证mock对象交互行为的方法是verify(mock). xxx()。于是用此方法验证了findUserByUserName()方法的调用,因为只调用了一次,所以在verify中我们指定了times参数或atLeastOnce()参数。最后验证返回值是否和预期一样。
代码清单16 10 MockitoSampleTest.java验证交互行为
import org.junit.Test;
import org.mockito.Mock;
import com.baobaotao.domain.User;
import com.baobaotao.service.UserService;
import com.baobaotao.service.UserServiceImpl;
public class MockitoSampleTest {
//① 模拟接口UserService测试
@Test
public void testMockInterface() {
when(mockUserService.findUserByUserName("tom"))
.thenReturn(new User("tom", "1234"));
User user = mockServiceImpl.findUserByUserName("tom");
//①-4 验证返回值
assertNotNull(user);
assertEquals(user.getUserName(), "tom");
assertEquals(isMatch, true);
//①-5 验证交互行为
verify(mockUserService).findUserByUserName("tom");
//①-6 验证方法至少调用一次
verify(mockUserService, atLeastOnce()).findUserByUserName("tom");
verify(mockUserService, atLeast(1)).findUserByUserName("tom");
//①-7 验证方法至多调用一次
verify(mockUserService, atMost(1)).findUserByUserName("tom");
}
}
Mockio为我们提供了丰富调用方法次数的验证机制,如被调用了特定次数verify(xxx, times(x))、至少x次verify(xxx, atLeast (x))、最多x次verify(xxx, atMost (x))、从未被调用verify(xxx, never())。在①-6处,验证findUserByUserName()方法至少被调用一次。在①-7处,验证findUserByUserName()方法至多被调用一次。
分享到:
相关推荐
PMP模拟测试概述 - **模拟测试目的**:该模拟测试旨在帮助PMP考生评估自己的准备情况,熟悉考试形式和题型。 - **测试内容**:涵盖PMP认证考试的1-13章内容。 - **测试结构**: - 共有180道选择题。 - 完成时间...
首先,我们从“软件测试概述”开始。软件测试是验证和确认软件产品是否满足预定需求的过程。它不仅仅是找出错误,更是评估软件的性能、兼容性、安全性等多个方面。测试过程通常包括单元测试、集成测试、系统测试和...
零售网点概述模拟测试.pdf
**测试工具**是提高测试效率和准确性的重要手段,例如JMeter,这是一个开源的性能测试工具,主要用于模拟大量并发用户进行负载和压力测试。JMeter可以用于测试Web应用的性能,如响应时间和吞吐量,从而帮助识别系统...
2. **压力测试**:模拟高并发访问情况,评估系统最大承受能力和稳定性。 3. **负载测试**:在逐步增加负载的情况下观察系统的性能变化趋势。 4. **稳定性测试**:长时间运行测试,观察系统是否会出现性能下降或崩溃...
一、性能测试概述 性能测试是为了评估软件系统在特定工作负载下的响应时间、吞吐量和资源利用率等性能特性。它不仅关注软件在正常情况下的运行效率,还关注在极限条件下的表现,比如大量用户同时访问或处理大数据量...
### 数据库测试概述 #### 一、什么是数据库测试? 数据库测试是指对数据库系统进行全面的质量评估活动,它旨在确保数据库能够正确、高效、安全地存储、处理和检索数据。虽然目前并没有一个官方定义来准确描述...
16.3.1 模拟测试概述 16.3.2 创建Mock对象 16.3.3 设定Mock对象的期望行为及返回值 16.3.4 验证交互行为 16.4 测试整合之王Unitils 16.4.1 Unitils概述 16.4.2 集成Spring 16.4.3 集成Hibernate 16.4.4 集成Dbunit ...
16.3.1 模拟测试概述 16.3.2 创建Mock对象 16.3.3 设定Mock对象的期望行为及返回值 16.3.4 验证交互行为 16.4 测试整合之王Unitils 16.4.1 Unitils概述 16.4.2 集成Spring 16.4.3 集成Hibernate 16.4.4 集成Dbunit ...
#### 一、神州数码锐行测试环境模拟平台概述 - **平台定位**: 神州数码锐行测试环境模拟平台是一款业内领先的虚拟测试工具软件,专注于构建虚拟测试环境,旨在通过一系列高级功能为用户提供一套完整的自动化测试解决...
### 软件测试认证模拟题解析 #### 1. 捕获与重放工具的应用场景 **知识点概述:** 捕获与重放(Capture and Replay)工具是软件测试过程中的一种辅助工具,主要用于自动化测试。这种工具可以记录用户的交互行为,并...
* 测试环境与测试辅助工具可以帮助测试人员模拟实际应用场景。 * 测试环境与测试辅助工具可以提高测试工作效率,减少测试时间和测试成本。 * 测试环境与测试辅助工具可以帮助测试人员发现软件中的bug。 学生信息...
面向对象的系统测试概述 面向对象的系统测试概述是软件开发中的一种重要测试方法,它关注于对象的行为和交互,以确保软件系统的正确性和可靠性。本文将对面向对象的基本概念、面向对象的实质、对象之间的关系、面向...
本篇将详细探讨利用电动助力转向系统测试平台进行模拟测试性能的方法,旨在帮助理解和优化EPAS系统的功能。 一、电动助力转向系统概述 电动助力转向系统区别于传统的液压助力转向,通过电动机提供助力,降低了能源...
- 稳定性:通过长时间运行、压力测试、异常模拟等方式检查软件崩溃、重启等问题。 - 安全性:测试数据加密、权限管理、隐私保护等功能,防止数据泄露或被恶意利用。 - 兼容性:确保软件在不同操作系统版本、屏幕...
本文档将深入探讨一种综合性电池管理系统模拟测试平台的设计与应用,旨在为相关行业的专业人员提供有价值的参考。 一、电池管理系统(BMS)概述 BMS的核心功能包括电池状态估计(SOX:State of Charge/Health/...
"自动驾驶汽车测试场景概述" 自动驾驶汽车测试场景概述是指自动驾驶汽车测试过程中所需的各种测试场景的集合,包括道路测试、停车场景、死胡同、高速公路式街道等。这些场景的设计和搭建对自动驾驶汽车的测试效率和...
本讲座主要概述了Web安全测试的关键概念和技术,旨在帮助测试人员和开发人员更好地理解如何保护Web应用程序免受攻击。 首先,我们要明确,Web安全测试并不是一种全新的测试方法,它与传统测试有许多相似之处。它们...