徐昊 · TDD 项目实战 70 讲
徐昊
Thoughtworks 中国区 CTO
18159 人已学习
新⼈⾸单¥98
登录后,你可以任选4讲全文学习
课程目录
已完结/共 88 讲
实战项目二|RESTful开发框架:依赖注入容器 (24讲)
实战项目三|RESTful Web Services (44讲)
徐昊 · TDD 项目实战 70 讲
15
15
1.0x
00:00/00:00
登录|注册

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

视频演示

进入今天的环节:
00:00 / 00:00
    1.0x
    • 2.0x
    • 1.5x
    • 1.25x
    • 1.0x
    • 0.75x
    • 0.5x
    网页全屏
    全屏
    00:00

    思考题

    接下来要重构还是继续完成功能,让坏味道再多一点?
    确认放弃笔记?
    放弃后所记笔记将不保留。
    新功能上线,你的历史笔记已初始化为私密笔记,是否一键批量公开?
    批量公开的笔记不会为你同步至部落
    公开
    同步至部落
    取消
    完成
    0/2000
    荧光笔
    直线
    曲线
    笔记
    复制
    AI
    • 深入了解
    • 翻译
      • 英语
      • 中文简体
      • 中文繁体
      • 法语
      • 德语
      • 日语
      • 韩语
      • 俄语
      • 西班牙语
      • 阿拉伯语
    • 解释
    • 总结

    本文介绍了如何使用TDD的方式实现RESTful Web Services,并围绕着架构愿景和任务列表展开讨论。文章中提到了已经实现的ResourceRouter、UriTemplate等内容,并给出了相关的代码示例。作者还提出了一个思考题,即接下来是重构还是继续完成功能。整体来看,本文主要围绕RESTful Web Services的实现展开,通过代码示例和思考题引发读者对于相关技术的思考和讨论。

    仅可试看部分内容,如需阅读全部内容,请付费购买文章所属专栏
    《徐昊 · TDD 项目实战 70 讲》
    新⼈⾸单¥98
    立即购买
    登录 后留言

    全部留言(2)

    • 最新
    • 精选
    • 忘川
      重构的收益: 1. 降低理解难度 2. 提高复用 3. 培养对象内聚的感觉 所以 重构越早收益越高
      2023-01-09归属地:上海
    • aoe
      三角法补充 1、使用数据驱动进行测试 2、两个测试不可能使用伪实现同时通过
      2022-07-25
    收起评论
    大纲
    固定大纲
    回顾架构愿景与任务列表
    视频演示
    思考题
    显示
    设置
    留言
    2
    收藏
    沉浸
    阅读
    分享
    手机端
    快捷键
    回顶部