`should respond_with_content_type`和`should respond_with`会因为响应为零而失败

时间:2013-01-17 20:51:41

标签: ruby-on-rails-3 unit-testing tdd rspec-rails shoulda

在以下测试中,我期待我的网页访问者未登录以获得“404'并且对于html的响应的内容类型,我已经表达过这样的话:

require 'spec_helper'
require 'rspec-rails'
#require 'shoulda'
#require 'shoulda-matchers'
#require 'shoulda/matchers/action_controller'
describe StaticPagesController do
  context "home page without being logged in" do
    before { visit root_path }
    it { should respond_with :missing }
    it { should respond_with_content_type :html }
    it { should_not render_template :application }
    it { should_not render_with_layout }
    it { should_not set_the_flash }
  end
end

这是受测试的控制器:

class StaticPagesController < ApplicationController
  def home
    if signed_in?
      redirect_to user_path
    else
      render layout: false,
             file: %Q(#{ Rails.root }/public/404),
             formats: [:html],
             status: '404'
    end
  end
end

当我执行测试时,respond_withrespond_with_content_type匹配器失败,

NoMethodError: undefined method `content_type' for nil:NilClass
/home/rev/.rvm/gems/ruby-1.9.3-p194/gems/shoulda-matchers-\
1.4.2/lib/shoulda/matchers/action_controller/\
respond_with_content_type_matcher.rb:59:in `response_content_type'

NoMethodError: undefined method `response_code' for nil:NilClass
/home/rev/.rvm/gems/ruby-1.9.3-p194/gems/shoulda-matchers-\ 
1.4.2/lib/shoulda/matchers/action_controller/respond_with_matcher.rb:57:
in `response_code'

这对我来说很奇怪,因为这些方法是:

    def response_content_type
      @controller.response.content_type.to_s
    end

    def response_code
      @controller.response.response_code
    end

这意味着@controller的响应为空或@controller为零,这是可能的,但并不反映我在浏览器中看到的行为。< / p>

我的猜测,鉴于我在这方面完成了n00b(一般来说是Ruby / Rails / RSpec / etc / MVC开发),我是否已经忘记了一两块宝石,或者我可能已经忘记了。我做了别的蠢事,但我无法猜出是什么,并且几天的搜索天堂没有发现任何有用的线索。这是当前的宝石环境:

 thor (0.16.0)
 bundler (1.2.1)
 childprocess (0.3.6)
 sprockets (2.2.2)
 rspec-mocks (2.12.1)
 rspec (2.12.0)
 selenium-webdriver (2.27.2)
 actionmailer (3.2.11)
 rdoc (3.12)
 polyglot (0.3.3)
 shoulda-matchers (1.4.2)
 mocha (0.10.5)
 rack-ssl (1.3.2)
 metaclass (0.0.1)
 shoulda-context (1.0.2)
 bcrypt-ruby (3.0.1)
 mime-types (1.19)
 websocket (1.0.6)
 rspec-rails (2.12.2)
 rspec-expectations (2.12.1)
 rack-test (0.6.2)
 lumberjack (1.0.2)
 treetop (1.4.12)
 stream (0.5)
 sass (3.2.5)
 listen (0.7.2)
 guard-rspec (2.4.0)
 bourne (1.1.2)
 xpath (1.0.0)
 uglifier (1.3.0)
 mail (2.4.4)
 nokogiri (1.5.6)
 activeresource (3.2.11)
 journey (1.0.4)
 rails (3.2.11)
 i18n (0.6.1)
 coderay (1.0.8)
 activemodel (3.2.11)
 activerecord (3.2.11)
 libwebsocket (0.1.7.1)
 rack-cache (1.2)
 builder (3.0.4)
 guard (1.6.1)
 rake (10.0.3)
 bootstrap-sass (2.2.2.0)
 coffee-script-source (1.4.0)
 slop (3.4.3)
 active_attr (0.7.0)
 rack (1.4.4)
 debugger-ruby_core_source (1.1.6)
 debugger (1.2.3)
 columnize (0.3.6)
 coffee-script (2.2.0)
 ffi (1.3.1)
 shoulda (3.3.2)
 sass-rails (3.2.6)
 arel (3.0.2)
 jquery-rails (2.1.4)
 debugger-linecache (1.1.2)
 tilt (1.3.3)
 coffee-rails (3.2.2)
 hike (1.2.1)
 actionpack (3.2.11)
 rb-inotify (0.8.8)
 railties (3.2.11)
 pry (0.9.11.2)
 rspec-core (2.12.2)
 rgl (0.4.0)
 diff-lcs (1.1.3)
 activesupport (3.2.11)
 addressable (2.3.2)
 libnotify (0.5.9)
 capybara (2.0.2)
 json (1.7.6)
 erubis (2.7.0)
 guard-spork (1.4.1)
 execjs (1.4.0)
 multi_json (1.5.0)
 tzinfo (0.3.35)
 spork (0.9.2)
 sqlite3 (1.3.7)
 method_source (0.8.1)
 rubyzip (0.9.9)

如果我遗漏了上述任何有用信息,请告知我们。

有关如何确定@controller@controller.response为何在此处为零的任何建议?我粗略地试图追查执行情况并不富有成效。

提前致谢,

Derrell

1 个答案:

答案 0 :(得分:1)

尝试将before { visit root_path }替换为before { get :home }

“访问”语法通常与完整堆栈验收规范一起使用,由Capybara和Webrat等库提供。 RSpec提供了一个特殊的上下文和辅助方法,用于在控制器规范中执行单个操作,您可以在这里阅读更多信息:https://www.relishapp.com/rspec/rspec-rails/v/2-12-2/docs/controller-specs。调用get(:home)将模拟对被测控制器的“home”动作的GET请求。我相信这会将@controller设置在引擎盖下,正如你的发布者所期望的那样。

您可能还需要模拟记录用户以在控制器操作中测试user_signed_in?的真假案例。如果您正在使用Devise,Devise wiki在设置RSpec控制器规范方面有很好的演练。