如何对你的 API 进行单元测试?

How to unit test your API?

提问人:deceze 提问时间:6/28/2010 最后编辑:deceze 更新时间:2/10/2015 访问量:22351

问:

我现在需要为使用 CakePHP 1.3 编写的 REST API 编写单元测试。API 支持 GET、POST 和 PUT 请求来查询和操作数据。

是否有任何既定的方法可以使用固定装置测试模拟 HTTP 请求的 API 的正确输入/输出?我不想对实时(dev)数据库运行实际的POST/PUT请求。如何才能最好地模拟系统以使用临时模型,同时按原样测试堆栈的其余部分?


使用控制器测试测试 GET 请求非常简单。但是,对于数据操作,API 非常广泛地使用 HTTP 标头,并且还解析原始 XML 和 JSON POST/PUT 数据。控制器单元测试方法仅通过在控制器中设置来模拟 POST 数据,这不允许我正确测试 API。$this->data

单元测试 API CakePHP

评论

3赞 wds 7/8/2010
如果你一次测试几乎整个堆栈,它就不再是真正的单元测试了,是吗?
0赞 deceze 7/9/2010
@wds 话又说回来,API 请求不就是对客户端的函数调用吗?为什么我不应该作为一个整体来测试它?
2赞 wds 7/12/2010
这只是一个命名的小问题。我称之为集成测试,而不是单元测试。
3赞 Craig Trader 8/27/2010
测试所有内容(即:集成测试)是必要的,但如果这是您唯一的测试形式,您将在隔离错误方面遇到问题。单元测试通常侧重于代码的一小部分,目的是证明特定部分确实符合预期(不多也不少)。
0赞 Peter 12/14/2012
如果“整个堆栈”意味着 Web 服务器(例如 Apache)->调度程序(可能是 PHP 层或 Apache URL 重写)->后端,那么我认为您希望单独测试这些层吗?我很想找到一种很好的方式来开发和管理“调度程序”层的测试 - 我只能想到使用真实的客户端来生成带有标头等的请求,然后在调度程序中使用一些额外的代码来捕获来自 Web 服务器的所有内容的所有详细信息,并自动生成一个可用于在没有客户端 + Web 服务器的情况下重放测试的夹具。你现在做什么?

答:

5赞 Craig Trader 6/28/2010 #1

我建议从一些研究开始。这些文章应该会有所帮助:

3赞 Don Kirkby 7/6/2010 #2

看起来您可能能够测试原始 XML PUT 和 POST 数据而不会遇到太多麻烦。CakePHP REST文档是这样说的:

如果 POST 或 PUT 请求具有 XML 内容类型,则输入将被获取并传递给 Cake 的 Xml 对象的实例,该实例分配给控制器的 $data 属性。由于此功能,并行处理 XML 和 POST 数据是无缝的:无需更改控制器或模型代码。您需要的一切都应该以 $this->data 结束。

尝试在调试模式下单步执行控制器代码,以查看 XML 请求期间实际输入的内容。$this->data

至于避免使用实时数据库,SQLite内存数据库会更容易吗?

评论

0赞 deceze 7/6/2010
我真的不在乎我使用的是什么类型的数据库,我想在测试表中使用夹具。这些只能通过部分模拟对象获得,这需要我跳过 API 中的一些低级部分。为了测试客户端看到的完整 API,我需要访问原始 POST/PUT 数据,因为我 a) 对发布的数据进行签名检查,b) 还需要测试发布的 JSON 数据。使用模拟对象和设置直接伪造过程在某种程度上起作用,但它不允许我将整个 API 请求/响应周期作为一个单元进行测试。$this->data
0赞 Don Kirkby 7/7/2010
@deceze,我在一些测试中使用了测试夹具,我不记得必须嘲笑任何东西。我认为,模拟对于测试控制器方法是必要的。已经几个月了,所以我可能忘记了一些细节。我按照这里的指示进行操作:book.cakephp.org/view/363/Testing-models
0赞 Don Kirkby 7/7/2010
如果您尝试测试 http 请求和控制器方法之间的循环部分,@deceze,那么我会将其作为集成测试单独处理。只需测试一次,因为它都是由 CakePHP 路由代码处理的。然后,对于每个控制器方法,您可以编写更简单的单元测试,而无需担心路由。
0赞 deceze 7/7/2010
这显然是我必须要做的,这真的很不幸。因为这意味着我将不得不嘲笑系统中通常依赖于实际请求的某些部分。还因为这意味着我无法真正编写请求/响应测试来确保 API 按客户端 POV 的预期工作。
7赞 Teoman shipahi 1/14/2015 #3

您应该创建 Mock 或使用 Isolation Framework 来模拟 API 环境。单元测试不应依赖于 Internet 连接、网络、端点等资源。

如果您打算测试真实的 API 调用,您应该创建集成测试项目并将其用于此目的。但请注意,集成测试大多是不可重复的,每次运行都会给你不同的结果。