【问题标题】:Undefined method "contain" for controller spec控制器规范的未定义方法“包含”
【发布时间】:2014-01-24 06:16:55
【问题描述】:

绝对最好将规范分开,这样您就有了与 MVC 架构的各个方面相关的规范,但我认为控制器规范和视图规范有轻微的交叉。

对于视图规范,您应该只关心视图,但对于控制器规范,我仍然认为测试是否呈现正确的视图是一个好主意,甚至可能测试视图的内容,尽管更多应在视图规范中对内容进行深入测试。

尽管有这篇清晰的文章 https://www.relishapp.com/rspec/rspec-rails/v/2-1/docs/controller-specs/render-views 描述了如何做到这一点,但我无法整合我的视图和控制器规范。

我不断收到错误 undefined method 'contain'!

这是我的 spec_helper:

# This file is copied to spec/ when you run 'rails generate rspec:install'
ENV["RAILS_ENV"] ||= 'test'
require File.expand_path("../../config/environment", __FILE__)
require 'rspec/rails'


require 'capybara/rspec'
require 'capybara/rails'

require 'factory_girl_rails'
require 'ap'

def set(factory)
  @user = FactoryGirl.create(factory) 
end

def sign_up(first_name, last_name, profile_name, email, password)
    visit "/"
    click_link "Register"
    fill_in('First name', with: first_name)
    fill_in('Last name', with: last_name)            
    fill_in('Profile name', with: profile_name)
    fill_in('Email', with: email)
    fill_in('Password', with: password)
    fill_in('Password confirmation', with: password)
    click_button 'Sign up'
end

def sign_in(email, password)
    visit "/"
    click_link "Sign In"
    fill_in('Email', with: email)
    fill_in('Password', with: password)
    click_button 'Sign in'
end

def sign_out
    visit "/"
    click_link "Sign Out"
end



#Webrat.configure do |config|
#  config.mode = :rails
#end

#webrat

require 'capybara/poltergeist'
# Capybara.javascript_driver = :poltergeist


Capybara.javascript_driver = :selenium


Dir[Rails.root.join("spec/support/**/*.rb")].each { |f| require f }

# Checks for pending migrations before tests are run.
# If you are not using ActiveRecord, you can remove this line.
ActiveRecord::Migration.check_pending! if defined?(ActiveRecord::Migration)


RSpec.configure do |config|
  # true means 'yes, filter these specs'
  config.filter_run_excluding stress: true
 # config.current_driver = :webkit
#  config.use_transactional_fixtures = false

#  config.include Capybara::DSL


  DatabaseCleaner.strategy = :truncation


  config.after(:suite) do
    DatabaseCleaner.clean_with(:truncation)
  end

#  config.before(:suite) do
  #  DatabaseCleaner.strategy = :transaction
 #   DatabaseCleaner.clean_with(:truncation)
#    DatabaseCleaner.start
 # end

 # config.after(:each) do
 #   DatabaseCleaner.clean
 # end

  #config.after(:suite) do
#   DatabaseCleaner.strategy = :transaction
#   DatabaseCleaner.clean_with(:truncation)
  #  DatabaseCleaner.clean
 # end


  # Remove this line if you're not using ActiveRecord or ActiveRecord fixtures
  # config.fixture_path = "#{::Rails.root}/spec/fixtures"

  # config.include RSpec::Rails::RequestExampleGroup, type: :feature

  # If you're not using ActiveRecord, or you'd prefer not to run each of your
  # examples within a transaction, remove the following line or assign false
  # instead of true.
  config.use_transactional_fixtures = true



  I18n.enforce_available_locales = true

  # If true, the base class of anonymous controllers will be inferred
  # automatically. This will be the default behavior in future versions of
  # rspec-rails.
  config.infer_base_class_for_anonymous_controllers = false

  # Run specs in random order to surface order dependencies. If you find an
  # order dependency and want to debug it, you can fix the order by providing
  # the seed, which is printed after each run.
  #     --seed 1234
  config.order = "random"
end

这是我的控制器规格:

require "spec_helper"

describe UserFriendshipsController, type: :controller do
    render_views
    let (:user_1) { FactoryGirl.create(:user_1)} 

    before { 
        sign_in user_1
        get :index
    }   

    it "renders the :index view" do
        response.should render_template(:index)
    end

    it "view contains expected html" do
        # a sanity test more than anything
        response.should contain("Welcome to the home page")
    end
end

运行此规范后,我得到以下信息:

.F

Failures:

  1) UserFriendshipsController view contains expected html
     Failure/Error: response.should contain("Listing widgets")
     NoMethodError:
       undefined method `contain' for #<RSpec::Core::ExampleGroup::Nested_1:0x00000008632268>
     # ./spec/controllers/user_friendships_spec.rb:18:in `block (2 levels) in <top (required)>'

Finished in 0.1835 seconds
2 examples, 1 failure

为什么会这样?我怎样才能让它工作?

【问题讨论】:

标签: ruby-on-rails rspec


【解决方案1】:

如果您查看relish documentation for the current 2.14 version of Rspec,您会发现他们现在使用的是match

expect(response.body).to match /Listing widgets/m

使用should 语法,这应该可以工作:

response.body.should match(/Welcome to the home page/)

【讨论】:

  • 我知道你不应该在这个网站上这样做,但非常感谢 Dylan!
  • 对于将来阅读此内容的任何人 - 如果他们想要测试的不是完全匹配,而是响应中有名称,您可以使用此包含匹配器。例如:expect(rendered).to include(@widgets.first.name)
【解决方案2】:

是的,是 Rspec 的一篇非常不清楚的文章导致了这个错误。它在其示例中使用了 webrat,并没有想告诉你。如果其他人来到这里,您可以将 webrat 添加到您的 gemfile 以使用 contains 方法:

宝石文件

group :test do
    gem 'webrat'
end

但是,使用 rspec 的原生匹配方法更有意义:

expect(response.body).to match /Listing widgets/m

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-01-12
    • 1970-01-01
    • 1970-01-01
    • 2022-11-05
    相关资源
    最近更新 更多