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

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

因此,合理的单元测试应该是一个类写一个测试,涉及到的其他引用类怎么办? 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));

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值