博客分类:
虽然easymock中提供了大量的方法来进行参数匹配,但是对于一些特殊场合比如参数是复杂对象而又不能简单的通过equals()方法来比较,这些现有的参数匹配器就无能为力了。easymock为此提供了IArgumentMatcher 接口来让我们实现自定义的参数匹配器。
我们还是用例子来说话:
public interface Service {
public void execute(Request request);
} service类的execute()方法接收一个Request实例作为参数, Request是一个javabean:
public static class Request {
private boolean condition;
private String value1;
private String value2;
//ignore getter and setter method
} 假设在我们的这个单独的测试案例中,我们有以下参数匹配逻辑: 如果condition为true,则只需要比较value1;如果condition为false,则只需要比较value2. 由于这个逻辑和默认的equals方法不一致,因此我们不能直接使用equals方法,只能实现自己的参数匹配器。
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;
}
} RequestMatcher 是我们定义的参数匹配器,matches()方法中是参数匹配逻辑的代码实现,appendTo()方法用于在匹配失败时打印错误信息,后面我们会演示这个方法的使用。然后是最重要的方法requestEquals(),在这里我们通过调用EasyMock.reportMatcher()告诉easymock我们要用的参数匹配器。
在测试案例中,我们和以往一样,先创建了mock对象,然后准备request对象作为测试数据。不同的是,我们没有使用easymock提供的参数匹配方法,而是通过service.execute(RequestMatcher.requestEquals(expectedCondition, expectedValue)); 来调用EasyMock.reportMatcher(),以创建我们自定义的参数匹配器并为它传入了两个必备的参数expectedCondition和expectedValue。
上面的测试案例可以顺利通过,我们的参数匹配器可以正常工作。然后我们来试试参数匹配不成功的情况
@Test
public void testConditionTrueFailure() {
final boolean expectedCondition = true;
final String expectedValue = "aaa";
Service service = EasyMock.createMock("service", Service.class);
Request request = prepareRequest(expectedCondition, "bbb", "ccc");
service.execute(RequestMatcher.requestEquals(expectedCondition, expectedValue));
EasyMock.expectLastCall();
EasyMock.replay(service);
service.execute(request);
EasyMock.verify(service);
} 注意在Request request = prepareRequest(expectedCondition, "bbb", "ccc")中,我们故意设置value为和期望的不同,当然这样测试案例就通不过了:
java.lang.AssertionError:
Unexpected method call service.execute(net.sourcesky.study.easymock.tutorial.IArgumentMatcherTest$Request@10ef90c):
service.execute(RequestMatcher expect(condition=true expectedValue=aaa)): expected: 1, actual: 0
at org.easymock.internal.MockInvocationHandler.invoke(MockInvocationHandler.java:45)
at org.easymock.internal.ObjectMethodsFilter.invoke(ObjectMethodsFilter.java:73)
at $Proxy4.execute(Unknown Source)
at net.sourcesky.study.easymock.tutorial.IArgumentMatcherTest.testConditionTrueFailure(IArgumentMatcherTest.java:72)
注意"service.execute(RequestMatcher expect(condition=true expectedValue=aaa)): expected: 1, actual: 0"这行,其中的"RequestMatcher expect(condition=true expectedValue=aaa)"是我们在appendTo()方法中构建出来的错误信息。appendTo()方法只在这个时候才被调用,用于生成可读性强的错误信息以便我们在失败时检查,因此不要疏忽了这个方法的实现。
分享到:
相关推荐
#### 1.15 easymock教程-自定义参数匹配器 easymock还支持用户自定义参数匹配器,以满足更复杂的匹配需求。 - **创建匹配器**:通过实现`org.easymock.IArgumentMatcher`接口来创建自定义参数匹配器。 - **注册...
##### 1.15 自定义参数匹配器 - **自定义匹配器**:Easymock提供了默认的参数匹配机制,但在某些情况下可能需要更灵活的匹配规则,这时就可以使用自定义匹配器。 #### 四、最佳实践 ##### 1.16 命名Mock对象 - *...
- **匹配器**:使用EasyMock提供的匹配器(如`eq()`、`anyObject()`等)可以精确控制方法参数的匹配条件。 - **顺序模拟**:如果多个对象之间有特定的调用顺序,可以通过`EasyMock.sequence()`来指定。 **5. ...
- **匹配器**(Matchers):使用预定义或自定义的匹配器来验证方法参数。 理解这些基本概念和高级特性后,你就可以充分利用 EasyMock 来编写更精确、更全面的单元测试,提高代码的可靠性和可维护性。 在实践中,...
1. **特定参数匹配**:可以通过`EasyMock.eq()`等方法指定参数匹配规则,例如`expect(mockObject.getString(EasyMock.eq(1)))`。 2. **顺序验证**:可以设置方法调用的顺序,`EasyMock.inOrder()`用于创建顺序验证...
例如,我们可以创建自定义的匹配器,使得只有满足特定条件的参数才会触发预定义的模拟行为。 6. **Examples in the Archive**: "PowerMockStudy"这个文件夹可能包含了各种示例代码,这些代码展示了上述所有概念的...
在PowerMock测试中,使用ArgumentsMatcher来指定方法调用时的参数匹配规则。 ### Answerinterface #### 使用场景 当需要对方法调用做出复杂的响应时,可以实现Answer接口。 #### 业务代码 在业务代码中,可能会...
2. **匹配器(Matchers)**:你可以使用匹配器来匹配方法的参数,这样可以更灵活地定义期望。例如,`anyObject()`表示任何对象,`isA(Class)`则指定参数必须是某个类的实例。 3. **回调(Callbacks)**:JMock支持...