在编写 Rails 控制器测试时,为什么使用 #post vs #get vs #delete?

When writing Rails controller tests, why use #post vs #get vs #delete?

我意识到我不明白为什么 Rails 控制器测试/规范的结构是这样的。

在编写控制器测试时,我们被鼓励或多或少地将控制器视为一个单元并相应地编写单元测试,只关心控制器的输入和输出。例如,我们设置数据库的特定状态,也许存根一些 Devise 方法来模拟用户登录,当我们调用 post :create 或其他任何方法时,我们附加发送到该控制器操作的参数散列。

然后,对于输出,我们查看数据库的结果状态,检查响应 HTTP 代码和重定向等,以及将传递给模板渲染过程的任何分配变量。

控制器只是一个 Ruby class,它的 public 方法被调用以执行各种 RESTful 操作。所以在控制器规范中我们不会加载像 /kittens/new 这样的 URL;相反,我们直接调用控制器操作,如 get :new。路线不应该是相关的;它们只是系统的另一部分,决定为给定请求调用哪个控制器操作。

那么为什么我们在调用控制器操作时必须指定 HTTP 方法(如 getpostputdelete)?这不是一个外部细节,是路由工作原理的一部分吗?

出于好奇,我采用了我的一个控制器规格并切换了所有这些方法,最终得到了 delete :showget :create 之类的东西。 没有损坏。所以我很困惑:如果这些方法与我们在控制器规范中测试的代码没有相关细节,为什么我们要区分这些方法?

总结如下 (REST API - why use PUT DELETE POST GET?)

REST is a methodology for meaningful access of data. When you see a request in REST, it should immediately be apparant what is happening with the data.

因此,您在 HTTP 动词前加上旨在导致调用您的操作的结果。

这很重要,因为对于不使用 7 个默认控制器操作中的任何一个的场景。例如,disable_accounts,我们建议 GET /disabled_accounts 还是 PATCH /disabled_accounts

我不确定这是否就是它仍然存在的原因,但在 REST 之前,许多应用程序对 newcreate 使用相同的端点。 (比如,你可能有一个带有 new_review 动作的控制器,如果你用 GET 击中它,它会显示评论表单,如果你用 POST 击中它,它会保存评论。)在这些控制器操作中,您会看到 if request.post?.

如今,您很少看到它(谢天谢地),但它仍然受到支持。因此,通过将 HTTP 方法放入测试中,您可以确保 request 对象的行为方式符合您在控制器操作中的预期方式。