请求规范按预期工作;控制器规范允许:在不应该的情况下发布

发布于 2024-10-21 07:15:16 字数 1129 浏览 1 评论 0原文

为什么这个请求规范按其应有的方式工作:

require "spec_helper"

describe "POST on a GET route" do
  it "should not allow this" do
    post "/applicants/new"
    assert_response :missing
  end
end

但是在这个控制器规范中,GET、POST、PUT 和 DELETE 在不应该的情况下都以相同的方式工作:

require 'spec_helper'

describe ApplicantsController do
  it "should not allow this" do
    post :new
    should respond_with :missing # but it responds with 200
  end
end

更新:添加了 ApplicantsController 代码和路由定义:

class ApplicantsController < InheritedResources::Base    
  respond_to :html
  actions :index, :new, :create

  def new
    if current_user
      redirect_to resume_application_path and return
    end

    @applicant = Applicant.new
    @applicant.applications.build
    @applicant.build_user_detail
    new!
  end    
end

路由:

resources :applicants

更新:经过对 API 的大量研究和挖掘,我相信这是设计使然,因为控制器规范继承自 ActionController::TestCase,而请求规范继承自 ActionDispatch::IntegrationTest。对于控制器规范,HTTP 动词仅具有描述性。

有人可以确认这是设计使然吗?或者我应该提交错误报告?

谢谢你!

Why is it that this request spec works as it should:

require "spec_helper"

describe "POST on a GET route" do
  it "should not allow this" do
    post "/applicants/new"
    assert_response :missing
  end
end

But in this controller spec, GET, POST, PUT, and DELETE all work the same when they should not:

require 'spec_helper'

describe ApplicantsController do
  it "should not allow this" do
    post :new
    should respond_with :missing # but it responds with 200
  end
end

UPDATE: Added ApplicantsController code and route definition:

class ApplicantsController < InheritedResources::Base    
  respond_to :html
  actions :index, :new, :create

  def new
    if current_user
      redirect_to resume_application_path and return
    end

    @applicant = Applicant.new
    @applicant.applications.build
    @applicant.build_user_detail
    new!
  end    
end

Routes:

resources :applicants

UPDATE: After much researching and digging into the API, I believe this is by design as the Controller specs inherit from ActionController::TestCase while the Request specs inherit from ActionDispatch::IntegrationTest. In the case of Controller specs, the HTTP verbs become merely descriptive.

Could someone confirm that this is by design? Or should I file a bug report?

Thank you!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

我们只是彼此的过ke 2024-10-28 07:15:16

这似乎令人惊讶,但当您从单独测试控制器操作的角度来看它时,这是有道理的。通常,控制器操作不需要了解 HTTP 请求方法。指定不带方法的路由说明了这一点:

  match 'sample' => 'applicants#index'

现在 GET /samplePOST /sample 都将路由到索引操作。除非您为其编写代码,否则控制器将不知道 GET 和 POST 请求之间的区别。控制器规范不测试请求方法/操作组合是否可路由,因为这是路由引擎的责任。

您可以使用路由规范来验证哪些路由有效,哪些无效:

it "recognizes and generates #new" do
  { :get => "/applicants/new" }.should route_to(:controller => "applicants", 
      :action => "new")
end

it "does not recognize POST /applicants/new" do
  { :post => "/applicants/new" }.should_not be_routable
end

This seems surprising, but it makes sense when you look at it from the perspective of testing the controller actions in isolation. Normally, controller actions don't need to know about HTTP request methods. Specifying a route without a method illustrates this:

  match 'sample' => 'applicants#index'

Now GET /sample and POST /sample will both route to the index action. Unless you code for it, the controller will not know the difference between a GET and a POST request. Controller specs do not test whether request method/action combinations are routable, since that is the responsibility of the routing engine.

You can verify which routes work and which don't with routing specs:

it "recognizes and generates #new" do
  { :get => "/applicants/new" }.should route_to(:controller => "applicants", 
      :action => "new")
end

it "does not recognize POST /applicants/new" do
  { :post => "/applicants/new" }.should_not be_routable
end
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文