跳转至

57 RESTful Web Services(21):按照三角法,该如何增加新的测试案例?

你好,我是徐昊。今天我们继续使用TDD的方式实现RESTful Web Services。

回顾架构愿景与任务列表

目前我们已经实现了ResourceRouter,和UriTemplate整体的架构愿景如下:


目前的任务列表:

  • Resource/RootResource/ResourceMethod

  • 从Path标注中获取UriTemplate

    • 如不存在Path标注,则抛出异常
    • 在处理请求派分时,可以根据客户端提供的Http方法,选择对应的资源方法

    • 当请求与资源方法的Uri模版一致,且Http方法一致时,派分到该方法

    • 没有资源方法于请求的Uri和Http方法一致时,返回404
    • 在处理请求派分时,可以支持多级子资源

    • 当没有资源方法可以匹配请求时,选择最优匹配SubResourceLocater,通过它继续进行派分

    • 如果SubResourceLocator也无法找到满足的请求时,返回404

代码为:

class RootResourceClass implements ResourceRouter.RootResource {
    private PathTemplate uriTemplate;
    private Class<?> resourceClass;
    private List<ResourceRouter.ResourceMethod> resourceMethods;
    public RootResourceClass(Class<?> resourceClass) {
        this.resourceClass = resourceClass;
        this.uriTemplate = new PathTemplate(resourceClass.getAnnotation(Path.class).value());
        this.resourceMethods = Arrays.stream(resourceClass.getMethods()).filter(m -> Arrays.stream(m.getAnnotations())
                        .anyMatch(a -> a.annotationType().isAnnotationPresent(HttpMethod.class)))
                .map(m -> (ResourceRouter.ResourceMethod) new DefaultResourceMethod(m)).toList();
    }
    @Override
    public Optional<ResourceRouter.ResourceMethod> match(String path, String method, String[] mediaTypes, UriInfoBuilder builder) {
        UriTemplate.MatchResult result = uriTemplate.match(path).get();
        String remaining = result.getRemaining();
        return resourceMethods.stream().filter(m -> m.getUriTemplate().match(remaining).map(r -> r.getRemaining() == null)
                .orElse(false)).findFirst();
    }
    @Override
    public UriTemplate getUriTemplate() {
        return uriTemplate;
    }
    static class DefaultResourceMethod implements ResourceRouter.ResourceMethod {
        private UriTemplate uriTemplate;
        private Method method;
        public DefaultResourceMethod(Method method) {
            this.method = method;
            this.uriTemplate = new PathTemplate(method.getAnnotation(Path.class).value());
        }
        @Override
        public UriTemplate getUriTemplate() {
            return uriTemplate;
        }
        @Override
        public GenericEntity<?> call(ResourceContext resourceContext, UriInfoBuilder builder) {
            return null;
        }
        @Override
        public String toString() {
            return method.getDeclaringClass().getSimpleName() + "." + method.getName();
        }
    }
}

视频演示

进入今天的环节:

思考题

接下来要重构还是继续完成功能,让坏味道再多一点?

精选留言(2)
  • 忘川 👍(0) 💬(0)

    重构的收益: 1. 降低理解难度 2. 提高复用 3. 培养对象内聚的感觉 所以 重构越早收益越高

    2023-01-09

  • aoe 👍(0) 💬(0)

    三角法补充 1、使用数据驱动进行测试 2、两个测试不可能使用伪实现同时通过

    2022-07-25