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;
    }

}
复制代码
复制代码
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);
    }
}
复制代码

自定义匹配器

假设在我们的这个单独的测试案例中,我们有以下参数匹配逻辑: 如果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); } }
复制代码

 


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: WPF是一种强大的UI框架,它提供了许多控件,其中包括时间选择控件。但是,由于在特定的应用程序中,需要自定义时间选择以满足一些个性化需求。在这种情况下,可以使用WPF自定义控件来创建自己的时间选择控件。 首先,在WPF中创建时间选择控件,需要使用Calendar控件和TimePicker控件。Calendar控件用于显示日期,而TimePicker控件用于选择时间。时间选择控件的主体是StackPanel控件。在StackPanel控件中添加了两个控件Calendar和TimePicker,以实现时间选择的基本功能。 然后,需要在时间选择控件中定义一些附加属性,例如:选定日期、选定时间等等,以实现一些高级功能。 最后,为时间选择控件添加样式,并实现一些触发和动画效果,以使其外观和功能与应用程序的主题相匹配。 实现WPF自定义时间选择可能需要一些时间和经验,但对于需要一个不寻常的时间选择的应用程序来说,是值得的。 这样的时间选择是用户友好的,具有很好的设计和功能,并且以C#编写,可以很容易地与WPF应用程序集成。 ### 回答2: WPF自定义时间选择是一种功能强大、灵活性高的工具,它可以根据需求自行设计不同的选择,可以实现小时、分钟、秒数的选择等多种功能。 首先,我们需要使用WPF自带的DatePicker控件和TimePicker控件来实现时间选择。接下来,我们可以自定义控件的样式和模板,使其更符合我们的设计需求。 在自定义控件的样式时,我们需要设置控件的各个属性,比如控件的边框、背景、字体等。同时,我们可以通过设置样式来调整控件的布局和显示效果。 在时间选择的实现中,需要涉及到一些比较复杂的计算,比如计算时间的差值、时间的格式转换等。我们可以使用C#中的DateTime类和TimeSpan类来实现这些功能。 最后对于自定义时间选择的控件事件,需要自定义一些控件事件,使其更加符合我们的设计需求。比如增加或减少系统时钟里的时间。 总而言之,实现WPF自定义时间选择需要对WPF控件、样式、模板、计算和控件事件等各个方面有深入的了解。只有掌握了这些知识,才能够设计出优秀的时间选择,满足用户的需求。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值