在单元测试的过程中,我们希望仅仅测试一个类的功能是否正常,但是一个类中往往会引用其他类,而不得在测试一个类的同时其它类相关也进行了测试。 看上去结果很好,一个测试不仅测试了目标类又测试了其它类,但是这样的交叉测试导致一个致命问题,单元测试不再测试单一的类,一旦一个类出现问题会影响到多个单元测试,同样一个测试失败也不知道到底是哪个类出现问题。单元测试变成了集成测试,失去了单元测试的意义。
因此,合理的单元测试应该是一个类写一个测试,涉及到的其他引用类怎么办? 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); } }
mokedObject.someFunction(sameObject);
EasyMock.expectLastCall();
mokedObject.someFunction(EasyMock.isA(Object.class));