在创建mock对象的时候,我们可以命名mock对象。
前面我们谈到easymock中有三种mock对象,分别用下面三个方法创建:
createMock(Class<T> toMock)
createStrictMock(Class<T> toMock)
createNiceMock(Class<T> toMock)
带有命名功能的方法也有对应的三种:
createMock(String name, Class<T> toMock)
createStrictMock(String name, Class<T> toMock)
createNiceMock(String name, Class<T> toMock)
命名mock对象有什么好处呢?其实就是一点,即在当测试案例因为某个mock对象的状态或行为不符合要求而失败的时候,在异常信息里面可以输出这个mock对象的名称。
我们用实际的例子来看,同样是创建一个mock对象,然后调用一个没有record的方法,easymock报错退出的测试案例。
1. 不命名
Service service = EasyMock.createMock(Service.class);
异常信息如下:
java.lang.AssertionError:
Unexpected method call execute():
at org.easymock.internal.MockInvocationHandler.invoke(MockInvocationHandler.java:45)
at org.easymock.internal.ObjectMethodsFilter.invoke(ObjectMethodsFilter.java:73)
at net.sourcesky.study.easymock.tutorial.$Proxy4.execute(Unknown Source)
at net.sourcesky.study.easymock.tutorial.NamingMockTest$Business.execute(NamingMockTest.java:11)
at net.sourcesky.study.easymock.tutorial.NamingMockTest.testExecute(NamingMockTest.java:31)
......
这里的错误信息"Unexpected method call execute()",只指出了发生错误的是execute()方法,并未指出具体是哪个mock对象。
当测试案例简单时,比如就一两个mock对象,我们可以直接从方法名上就看出是哪个mock对象。但是当mock对象多了之后,尤其是方法很多的时候,就会浪费时间。
2. 命名后
Service service = EasyMock.createMock("service", Service.class);
异常信息如下:
java.lang.AssertionError:
Unexpected method call service.execute():
at org.easymock.internal.MockInvocationHandler.invoke(MockInvocationHandler.java:45)
at org.easymock.internal.ObjectMethodsFilter.invoke(ObjectMethodsFilter.java:73)
at net.sourcesky.study.easymock.tutorial.$Proxy4.execute(Unknown Source)
at net.sourcesky.study.easymock.tutorial.NamingMockTest$Business.execute(NamingMockTest.java:11)
at net.sourcesky.study.easymock.tutorial.NamingMockTest.testExecute(NamingMockTest.java:30)
差别只在错误信息中"Unexpected method call serviceMock.execute()" 包含serviceMock的字样,因此我们可以快递定位到具体的mock对象。
命名mock对象在初次编写测试案例时用处还不是很明显,因为编写者当时肯定对代码很熟悉。但是当另外一个开发人员因为某此修改代码造成测试案例不能通过时,由于这个开发人员对代码的熟悉程度不够,因此命名mock对象可以对他有所帮助,方便维护。
命名之后的mock对象,还有一个特殊的地方就是toString()方法将返回该mock对象的名称,以代码为例:
Service service = EasyMock.createMock("service", Service.class);
System.out.println(service.toString());
输出就是"service",对比不命名mock对象的情况:
Service service = EasyMock.createMock(Service.class);
System.out.println(service.toString());
得到的输出是"EasyMock for interface net.sourcesky.study.easymock.tutorial.NamingMockTest$Service".