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()的测试方法相同即可,就不再赘述了。

上一篇下一篇

猜你喜欢

热点阅读