easymock源码学习笔记(3)--录制

Easymock的基本思路就是在录制状态时将录制结果保存到IMocksBehavior中,当变为回放状态时从IMocksBehavior中取出录制结果。IMocksBehavior保存及取出预设值的类图如下


Range保存设定的调用次数;Result保存设定的值;Results根据调用次数的不同返回不同的值;Invocation 保存mock对象、函数、以及默认参数;IArgumentMatcher的实现类封装了函数参数的匹配方法;ExpectedInvocation判断mock对象调用的函数与录制函数是否匹配;ExpectedInvocationAndResults保存返回结果与调用函数间的对应关系;UnorderedBehavior添加预设值以及根据调用来返回相应的值;MocksBehavior根据mock的三种类型,确定换回值还是抛出异常。


easymock的录制过程即设定mock对象的预设值

EasyMock.expect(mock.oneArg(EasyMock.anyObject(String.class))).andReturn("2").times(1,2);                              

 //mock对象调用的方法匹配的参数

EasyMock.anyObject(String.class);

mock1.oneArg(null);

final IExpectationSetters exceptionSetters =EasyMock.expectLastCall();

exceptionSetters.andReturn("2");

exceptionSetters.times(1,2);


以上两种调用方法的结果相同,详细步骤为:

1、先将调用方法要参数匹配的类压入栈中

参数匹配类都在org.easymock.internal.matchers包中,类中封装的是参数的匹配算法,时序图如下:

LastControl类:

public static void reportMatcher(final IArgumentMatchermatcher) {

        Stack<IArgumentMatcher>stack = threadToArgumentMatcherStack.get();

        if (stack== null) {

            stack =new Stack<IArgumentMatcher>();

           threadToArgumentMatcherStack.set(stack);

        }

       stack.push(matcher);

}

压入栈中的个数必须与要录制的方法的参数相匹配的。

当将and、or参数匹配类压入栈中的时候会将栈顶的前两个元素合并为一个,因此栈中必须有两个元素。代码:

LastControl类:

public static void reportAnd(final int count) {

        finalStack<IArgumentMatcher> stack = threadToArgumentMatcherStack.get();

       assertState(stack != null, NO_MATCHERS_FOUND);

       stack.push(new And(popLastArgumentMatchers(count)));

}


EasyMock调用reportAnd方法时count=2.

2、调用要录制的方法

mock1.oneArg(null);

时序图:

以上两步主要是生成ExpectedInvocation对象,因为easymock返回预期结果时不仅调用函数相等而且要查看函数的参数是否匹配。

当1步没有时,将会在第2步调用要录制的方法生成ExpectedInvocation对象时,匹配对象设置为Equals类,当回放时调用函数的

参数对象必须与录制时的参数对象相等才会匹配。

3、设定预期结果

时序图如下:


3.1获取预期结果设置对象exceptionSetters

获取最后一次调用代理方法的mock对象对应的mockControl对象,而这个mock对象正是第2步中被MockInvocationHandler设置到LastControl中的mockControl对象。

3.2设定返回结果

exceptionSetters.andReturn("2")

为recordState对象属性lastResult赋值,但暂时不会加入到结果记录对象behavior当中。

RecordState类andReturn方法

public void andReturn(Object value) {

        //判断lastInvocation方法是否存在,没有则报错,因为预设的值必须对应invocation对象

       requireMethodCall("return value");

        //将值转换为相应的值

        value =convertNumberClassIfNeccessary(value);

        //判断预设的值类型与方法要求返还的类型是否相对应

       requireAssignable(value);

        //如果最后一次预设的值还没有保存,则保存

        if(lastResult != null) {

           times(MocksControl.ONCE);

        }

        lastResult= Result.createReturnResult(value);

    } 

3.3设定调用的次数

exceptionSetters.times(1,2),设定预设返回结果返回的次数,并将预设的结果保存到behavior中。

RecordState类中的times方法

 public void times(final Range range) {
        requireMethodCall("times");
        requireLastResultOrVoidMethod();
        behavior.addExpected(lastInvocation, lastResult != null ? lastResult : Result
                .createReturnResult(null), range);
        lastInvocationUsed = true;
        lastResult = null;
    }

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值