测试工具(二)——Easy Mock

来源:互联网 发布:java hello world程序 编辑:程序博客网 时间:2024/05/19 02:45

特点

修改函数名称和参数顺序,不会影响重构

支持返回 value和异常

支持检察方法的调用顺序

安装

Maven方式

<dependency>      <groupId>org.easymock</groupId>      <artifactId>easymock</artifactId>      <version>3.1</version>      <scope>test</scope>    </dependency>


 

手动需要

       Easymock   cglib (2.2) and Objenesis (1.2)

使用实例

1.  在测试类中,静态引入org.easymock.EasyMock的方法。  

2.  从需要模拟的接口创建Mock 对象,并建立关系

public void setUp() {        mock = createMock(Collaborator.class); // 1        classUnderTest = new ClassUnderTest();        classUnderTest.addListener(mock);    } 

3.       记录期待的行为(mock哪个函数调用等)

4.       Replay(mock)   支持多个mock作为参数

5.       对需要的类进行测试

6.       verify(mock)  支持多个mock作为参数

Mock对象

类型

       支持 StrictMockNiceMockMock Object三种方式。

       StrictMock:检查函数调用次序,创建方法EasyMock.createStrictMock()。也可以使用switch order checking on by calling checkOrder(mock, true) and switch it off by callingcheckOrder(mock, false)

       NiceMock使用 createMock创建出来的 mock 对象,如果没有录过,调用这个方法都会出 AssertionError,但如果使用 createNiceMock就不会了,会返回 0 , null , false这样的。

      普通的mock createMock.

重置

       Reset(Mock)

带名称的mock

 CreateMockString nameClass<T> toMock

 createStrictMock(String name, Class<T> toMock)

 createNiceMock(String name, Class<T> toMock)

部分mock

       对类的部分函数进行mock,当测试一个函数,该函数调用同类中的其他函数时,希望这个函数不被mockmock其他函数。

处理方法:

1.       考虑重构,这是一种bad design

2.       使用方法

ToMock mock = createMockBuilder(ToMock.class).addMockedMethod("mockedMethod").createMock();   只有addMockedMethod添加的方法会mock,但抽象方法默认mock


 

object method

       对象的四个方法 equals()  hashCode()  toString()  finalize()不能被修改

序列化

       Mock对象支持序列化,使用writeObject

多线程

       record阶段,mock不是线程安全的,不同的mock可以在不同的线程中同步录制

       replay阶段,mock是线程安全的,可通过 makeThredSafe修改状态

       checkIsUsedInOneThred 判断是否在一个线程中调用

函数

希望的行为

l  mock对象调用的次数限制:

expectLastCall().times(int times) 最后一个方法调用的次数。

指定返回值:

   封装expect(mock调用函数返回值).andReturn()

        expect(mock.voteForRemoval("Document")).andReturn((byte) 42);

处理例外

      expectLastCall().andThrow(Throwable throwable)

      expect(mock.fun()).andThrow(Throwable throwable)

    对于要指定返回值,异常,次数的mock期望,在该函数后使用,可在程序中使用多次。

相同函数返回不同值

       返回42三次,扔出runtimeException 四次,返回-42一次

expect(mock.voteForRemoval("Document"))        .andReturn((byte) 42).times(3)        .andThrow(new RuntimeException(), 4)        .andReturn((byte) -42);// 当参数不等于42时,总是返回-1expect(mock.voteForRemoval(not(eq("Document")))).andStubReturn(-1);

创建return values或者exception

       根据输入参数,动态创建return value,重构可能会破坏测试,如下

expect(l.remove(10)).andAnswer(new IAnswer<String>() {        public String answer() throws Throwable {            return getCurrentArguments()[0].toString();        }    }); //通过使用 andAnswer(IAnswer answer) 函数,在IAnswer的接口类中做具体处理


 

调用次数

       times(count)   times(min,max)   atLeastOnce()   anytime()   once() 

函数参数

       使用matcher,如:

           expect(mock.voteForRemovals(aryEq(documents))).andReturn(42);

支持的matcher有:

Eq(X value)

支持objectprimitive类型

anyBoolean(), anyByte(), anyChar(),anyDouble(), anyFloat(), anyInt(),anyLong(), anyObject(), anyObject(Class clazz),anyShort()

匹配任意值

eq(X value, X delta)

delta偏差内,为floatdouble

aryEq(X value)

Arrays.equals() 相等

isNull(), isNull(Class clazz)

 

notNull(), notNull(Class clazz)

 

same(X value)

 通过 ==判断

isA(Class clazz)

 

lt(X value), leq(X value), geq(X value),gt(X value)

 

startsWith(String prefix), contains(String substring), endsWith(String suffix)

 

matches(String regex), find(String regex)

 

and(X first, X second)

 

not(X value)

 

or(X first, X second)

 

cmpEq(X value)

Comparable.compareTo(X o)判断相等

cmp(X value, Comparator<X> comparator, LogicalOperator operator)

the operator is <,<=,>,>= or ==. Available for objects

capture(Capture<T> capture),captureXXX(Capture<T> capture)

不懂

自定义Matcher

        1.  实现接口org.easymock.IArgumentMatcher.

        2.  声明Matcher

构造函数mock

       用在测试类方法,但其他methodmocked

              ToMock mock = createMockBuilder(ToMock.class).withConstructor(1, 2, 3); // 1, 2, 3 are the constructor parameters

其他

mock的限制

equals() hasCode() finalize提供内置的支持

Final methodprivate method不能mock,如果调用将执行normal code

修改默认行为

    配置easymock.properties修改相应属性

多mock之间的调用顺序

       使用IMocksControl

EasyMockSupport

       是工具类,自动注册所有的mock;批量replayreset、校验。

       需要继承EasyMockSupport,调用其定义的函数,如replayAll()  verifyAll()