EassyMock实践 自定义参数匹配器

   虽然easymock中提供了大量的方法来进行参数匹配,但是对于一些特殊场合比如参数是复杂对象而又不能简单的通过equals()方法来比较,这些现有的参数匹配器就无能为力了。easymock为此提供了IArgumentMatcher 接口来让我们实现自定义的参数匹配器。

    我们还是用例子来说话:

要测试的接口

 

package MockTest;

public interface Service {
    void execute(Request request, MData[] mdata, int mode);
}

 

参数类型定义

package MockTest;

public class Request {
    private boolean condition;

    private String  value1;

    private String  value2;
    
    public boolean isCondition() {
        return condition;
    }

    public String getValue1() {
        return value1;
    }

    public String getValue2() {
        return value2;
    }

    public void setCondition(boolean condition) {
        this.condition = condition;
    }

    public void setValue1(String value1) {
        this.value1 = value1;
    }

    public void setValue2(String value2) {
        this.value2 = value2;
    }

    public Request(boolean condition, String value1, String value2) {
        super();
        this.condition = condition;
        this.value1 = value1;
        this.value2 = value2;
    }

}
View Code
package MockTest;

public class MData {
    public byte[] key;
    public byte[] data;
    
    public MData(byte[] key, byte[] data) {
        super();
        this.key = key;
        this.data = data;
    }

    public String toString() {
            return "key: " + new String(key) + ", data: " + new String(data);
    }
}
View Code

自定义匹配器

假设在我们的这个单独的测试案例中,我们有以下参数匹配逻辑: 如果condition为true,则只需要比较value1;如果condition为false,则只需要比较value2. 由于这个逻辑和默认的equals方法不一致,因此我们不能直接使用equals方法,只能实现自己的参数匹配器。

package MockTest;

import org.easymock.EasyMock;
import org.easymock.IArgumentMatcher;

public class RequestMatcher implements IArgumentMatcher {

    private boolean condition;

    private String  expectedValue;

    private RequestMatcher(boolean condition, String expectedValue) {
        this.condition = condition;
        this.expectedValue = expectedValue;
    }

    @Override
    public void appendTo(StringBuffer buffer) {
        buffer.append("RequestMatcher expect(condition=");
        buffer.append(condition);
        buffer.append(" expectedValue=");
        buffer.append(expectedValue);
        buffer.append(")");
    }

    @Override
    public boolean matches(Object argument) {
        if (!(argument instanceof Request)) {
            return false;
        }

        Request request = (Request) argument;
        if (condition) {
            return expectedValue.equals(request.getValue1());
        } else {
            return expectedValue.equals(request.getValue2());
        }
    }

    public static Request requestEquals(boolean condition, String expectedValue) {
        EasyMock.reportMatcher(new RequestMatcher(condition, expectedValue));
        return null;
    }
}

EqualsMData是为了演示当参数是对象数组的时候怎么实现参数匹配的.关键是要把Object对象强制性转换为对象数组.

package MockTest;

import org.easymock.EasyMock;
import org.easymock.IArgumentMatcher;

//实现IArgumentMatcher接口
class EqualsMData implements IArgumentMatcher {
    private MData[] expect;

    private MData[] actual;

    public EqualsMData(MData[] expect) {
        this.expect = expect;
    }

    public static MData[] ZSMDataEquals(MData[] expect) {
        //提交匹配要的自定义类
        EasyMock.reportMatcher(new EqualsMData(expect));
        return null;
    }
    
    @Override
    //这个方法实现匹配参数的逻辑
    public boolean matches(Object argument) {    //this method only can mathch one single parameter
        System.out.println("argument is" + argument);
        // TODO Auto-generated method stub
        if (argument == this.expect)
            return true;

        if (!(argument instanceof MData[]))
            return false;
        
        //matches没有提供接收数组的方法, 所以这里必须强制转换OjectweiMData[]
        actual = (MData[]) argument;

        int length = expect.length;
        if (length != actual.length)
            return false;

        for (int i = 0; i < length; i++) {
            // if (expect[i].key != actual[j].key || expect[i].data != actual[j].data) //error
            if (!expect[i].toString().equals(actual[i].toString()))
            // if(!Arrays.equals(expect, actual))//error
            {
                return false;
            }
        }

        return true;
    }

    @Override
    //这个方法是匹配错误后要打印的信息
    public void appendTo(StringBuffer buffer) {
        // TODO Auto-generated method stub

        buffer.append("EqualsMPut expect is: \n");
        for (int i = 0; i < expect.length; i++) {
            buffer.append(expect[i].toString());
        }

        buffer.append(" but actual is: \n");

        for (int j = 0; j < actual.length; j++) {
            buffer.append(expect[j].toString());
        }
    }

}

测试

package MockTest;

import org.easymock.*;
import org.junit.*;
import static org.easymock.EasyMock.*;

public class TestEasyMock {

    @Test
    public void testConditionTrueFailure() {
        final boolean expectedCondition = true;
        final String expectedValue = "aaa";

        Service service = EasyMock.createMock("service", Service.class);
        MData[] datas = { new MData("1001".getBytes(), "2001".getBytes()),
                new MData("1002".getBytes(), "2002".getBytes()),
                new MData("1003".getBytes(), "2003".getBytes()) };

        Request request = new Request(expectedCondition, "aaa", "ccc");

//参数匹配器每次只能实现一个参数匹配,所以对于多个参数,要实现多个自定义匹配器 service.execute( RequestMatcher.requestEquals(expectedCondition, expectedValue), EqualsMData.ZSMDataEquals(datas), anyInt()); EasyMock.expectLastCall(); EasyMock.replay(service);
// MData[] datas2 = { new MData("1001".getBytes(), "2001".getBytes())}; service.execute(request, datas, 1); EasyMock.verify(service); } }

 

posted @ 2015-01-27 15:26  Ydoing  阅读(665)  评论(0编辑  收藏  举报