EasyMock 单元测试过程中模拟相关类的实例

原创 2014年10月09日 17:06:04

在单元测试的过程中,我们希望仅仅测试一个类的功能是否正常,但是一个类中往往会引用其他类,而不得在测试一个类的同时其它类相关也进行了测试。 看上去结果很好,一个测试不仅测试了目标类又测试了其它类,但是这样的交叉测试导致一个致命问题,单元测试不再测试单一的类,一旦一个类出现问题会影响到多个单元测试,同样一个测试失败也不知道到底是哪个类出现问题。单元测试变成了集成测试,失去了单元测试的意义。 

因此,合理的单元测试应该是一个类写一个测试,涉及到的其他引用类怎么办? EasyMock正是为此而生,它可以模拟出一个相关类的的行为。具体来讲,一个类主要就是所拥有的方法的行为,而EasyMock可以预先设定一个方法传入什么样的参数返回什么样的值,并且可以设定在程序中调用多少次,等等。这样一来单元测试就是真正意义的“单元”测试,使得测试代码更加精准。

下面是一个简单的例子:

被测试类:

public class BaseAvailabilityService implements AvailabilityService {
	
	
	private IConvert convert;
	private IService service;
	private IProfileService profile;
	
	@Override
	public Availability getAvailability(AvailabilityCriteria criteria, Contract contract) {
		final HotelSearchCriteria hsc = (HotelSearchCriteria) criteria.getCriteria();
		final ChannelHotelMapping hotelMapping = profile.getChannelHotelMapping(contract.getChannelCode(), hsc.getUniqueHotelCode());
		
		GetAvailRS avail = service.getAvailability(hotelMapping.getChannel().getAccount(), convert.toGetAvailRQ(criteria, hotelMapping));
		return convert.toAvailability(avail, criteria.getGuestCount().getAdultCount(), hotelMapping, null);
	}
	@Required
	public void setConvert(IStarwoodConvert convert) {
		this.convert = convert;
	}

	@Required
	public void setService(IStarwoodService service) {
		this.service = service;
	}
	@Required
	public void setProfile(IProfileService profile) {
		this.profile = profile;
	}

}
测试代码:

public class AvailabilityServiceTest {
	
	private BaseAvailabilityService availService = new BaseAvailabilityService();
	private IConvert convert;
	private IService service;
	private IProfileService profile;
	@Before
	public void startup(){
		convert = EasyMock.createMock(IConvert.class);
		service = EasyMock.createMock(IService.class);
		profile = EasyMock.createMock(IProfileService.class);
		availService.setConvert(convert);
		availService.setProfile(profile);
		availService.setService(service);
	}
	@Test
	public void testGetAvailability(){
		ChannelHotelMapping mapping = new ChannelHotelMapping();
		mapping.setChannel(new Channel());
		
		AvailabilityCriteria availCriteria = new AvailabilityCriteria();
		availCriteria.setCriteria(new HotelSearchCriteria());
		availCriteria.setGuestCount(new GuestCount());
		
		GetAvailRQ getAvailRQ = new GetAvailRQ();
		
		EasyMock.expect(profile.getChannelHotelMapping(null, null)).andReturn(mapping);
		EasyMock.expect(service.getAvailability(new Account(null,null), getAvailRQ)).andReturn(new GetAvailRS());
		EasyMock.expect(convert.toAvailability(new GetAvailRS(), null,mapping, null)).andReturn(new Availability());
		EasyMock.expect(convert.toGetAvailRQ(availCriteria, mapping)).andReturn(getAvailRQ);
		EasyMock.replay(profile,service,convert);
		availService.getAvailability(availCriteria, new Contract());
		EasyMock.verify(profile,service,convert);
	}
}

以上的例子中,Mock的方法都有参数与返回值,如果是有参数没有返回值的方法, 完全不能这样模拟了,可以用一下方式, 即在模拟调用的下一行,执行expectLastCall():

mokedObject.someFunction(sameObject);
EasyMock.expectLastCall();

还有一个问题,如果是想设定一个方法无论传入任何值,都返回特定值,如何设定? 可以使用参数可以使用EasyMock.isA(SomeObject.class),只要是SomeObject的实例都将执行预设的行为,如:

mokedObject.someFunction(EasyMock.isA(Object.class));

版权声明:本文为博主原创文章,未经博主允许不得转载。

相关文章推荐

使用 EasyMock 更轻松地进行测试

本文转自:点击打开链接 测试驱动开发是软件开发的重要部分。如果代码不进行测试,就是不可靠的。所有代码都必须测试,而且理想情况下应该在编写代码之前编写测试。但是,有些东西容易测...

easymock教程-easymock的典型使用

关于easymock的典型使用方式,在easymock的官网文档中,有非常详尽的讲解,文档地址为 http://easymock.org/EasyMock3_0_Documentation.htm...

剑指Offer面试题7(Java版):用两个栈实现队列与用两个队列实现栈

题目:用两个栈实现一个队列。队列的声明如下,请实现它的两个函数appendTail和deletedHead,分别完成在队列尾部插入节点和在队列头部删除节点的功能。 我们通过一个具体的例子来分析该队列插...

剑指offer(java版)

面试题 2 :实现单例模式 1. 饿汉式单例类 public class SingletonClass { private static final SingletonClass insta...

easyMock简单入门例子 .

接口:   [java] view plaincopyprint? package com.inter;  public interface AddInter {  pu...

EasyMock 使用方法与原理剖析

EasyMock 是一套通过简单的方法对于指定的接口或类生成 Mock 对象的类库,它能利用对接口或类的模拟来辅助单元测试。本文将对 EasyMock 的功能和原理进行介绍,并通过示例来说明如何使...

关于iOS开发过程中单元测试的一点拙见

本人比较小白,从来没有接触过单元测试的问题。 近两天用几个小时查阅了一些单元测试有关的知识,发现大家大多数都在说怎么讲写测试用例的用处或者怎么建测试用例,但是,我一直没有找到关于什么是测试用例的文章,...

Junit 实例精讲基础教程(三) 使用@Test(timeout=5000)模拟超时进行单元测试

实际开发中,尤其是系统间的调用时,经常需要检测接口调用的时间,单元测试时,亦需要模拟超时场景。如果一个单元测试正在花费超过一个定义的“超时”来完成,一个TestTimedOutException将会抛...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:深度学习:神经网络中的前向传播和反向传播算法推导
举报原因:
原因补充:

(最多只允许输入30个字)