moco代码赏析七
2018-02-04 本文已影响0人
hopelty
今天看的是2012.11.6的三次提交。
第一次提交作者更改了包名(package name),第三次提交作者更改了netty的版本。我们就来着重的看一下第二次提交的一些细节。
首先,这次提交,作者增加了一个新功能,在request()方法中开始支持and/or方式的请求。and/or是什么意思呢?就是当调用and()方法时,传入的参数必须同时满足条件,才算满足。当调用or()方法时,传入的参数中只需一个满足条件即可。下面来看具体的实现细节,首先来看一下and()方法:
server.request(and(by(text("foo")), by(uri("/foo")))).response(text("bar"));
public static RequestMatcher and(RequestMatcher... matchers) {
return new AndRequestMatcher(matchers);
}
public class AndRequestMatcher implements RequestMatcher {
private RequestMatcher[] matchers;
public AndRequestMatcher(RequestMatcher[] matchers) {
this.matchers = matchers;
}
@Override
public boolean match(HttpRequest request) {
for (RequestMatcher matcher : matchers) {
if (!matcher.match(request)) {
return false;
}
}
return true;
}
}
and()方法返回值也是matcher类型的实现类,叫做AndRequestMatcher。重写了其中的match()方法,遍历and()方法中传入的所有matcher,判断是否所有matcher都可以match得上,如果其中有一个使得match()方法返回值为false即返回false。再来看一下针对and()方法的测试类(一正例一反例):
public void should_match_request_based_on_multiple_matchers() {
server.request(and(by(text("foo")), by(uri("/foo")))).response(text("bar"));
running(server, new Runnable() {
@Override
public void run() {
try {
Content content = Request.Post("http://localhost:8080/foo").bodyByteArray("foo".getBytes())
.execute().returnContent();
assertThat(content.asString(), is("bar"));
} catch (IOException e) {
throw new RuntimeException(e);
}
}
});
}
有uri()、有text()。
@Test(expected = RuntimeException.class)
public void should_throw_exception_even_if_match_one_of_conditions() {
server.request(and(by(text("foo")), by(uri("/foo")))).response(text("bar"));
try {
Request.Get("http://localhost:8080/foo").execute().returnContent();
} catch (IOException e) {
throw new RuntimeException(e);
}
}
只有uri(),没有text()。
下面再来看一下or()方法。
server.request(or(by(text("foo")), by(uri("/foo")))).response(text("bar"));
public static RequestMatcher or(RequestMatcher... matchers) {
return new OrRequestMatcher(matchers);
}
public class OrRequestMatcher implements RequestMatcher {
private RequestMatcher[] matchers;
public OrRequestMatcher(RequestMatcher[] matchers) {
this.matchers = matchers;
}
@Override
public boolean match(HttpRequest request) {
for (RequestMatcher matcher : matchers) {
if (matcher.match(request)) {
return true;
}
}
return false;
}
}
该方法的返回值也是一个matcher类型的实现类,叫做OrRequestMatcher。重写了match()方法,遍历所有的matcher,查看所有的matcher是否至少有一个可以满足条件。当有一个使得match()方法能够返回true时,即返回true。同样的,来看一下or()方法的测试方法:
public void should_match_request_based_on_either_matcher() {
server.request(or(by(text("foo")), by(uri("/foo")))).response(text("bar"));
running(server, new Runnable() {
@Override
public void run() {
try {
Content uriResult = Request.Get("http://localhost:8080/foo").execute().returnContent();
assertThat(uriResult.asString(), is("bar"));
Content contentResult = Request.Post("http://localhost:8080").bodyByteArray("foo".getBytes())
.execute().returnContent();
assertThat(contentResult.asString(), is("bar"));
} catch (IOException e) {
throw new RuntimeException(e);
}
}
});
}
分别测试了只有text()和只有uri()时是否可以成功返回。
最后,作者还提供了一个方法,在request()中直接传入多个matcher:
public Setting request(RequestMatcher... matchers) {
return request(or(matchers));
}
实际还是调用的or()方法,测试方法只需要和or()的测试方法相同即可,就不再赘述了。