请求规范按预期工作;控制器规范允许:发布时不应该

时间:2011-03-08 03:31:52

标签: ruby-on-rails rest rspec2 controllers

为什么此请求规范应该按原样运行:

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

更新:经过大量研究和深入研究,我相信这是设计的,因为Controller规范继承自ActionController :: TestCase,而Request规范继承自ActionDispatch :: IntegrationTest。在Controller规范的情况下,HTTP动词仅仅是描述性的。

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

谢谢!

1 个答案:

答案 0 :(得分:3)

这看起来很令人惊讶,但从单独测试控制器操作的角度来看它是有意义的。通常,控制器操作不需要知道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