4

我在控制器测试中得到了一个未定义的“应该”方法,但无法弄清楚原因。我花了一些时间在谷歌和堆栈溢出上,但被卡住了。有什么帮助吗?

规范助手:

require 'simplecov'
SimpleCov.start 'rails'

# 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 'rspec/autorun'
# Requires supporting ruby files with custom matchers and macros, etc,
# in spec/support/ and its subdirectories.
Dir[Rails.root.join("spec/support/**/*.rb")].each {|f| require f}

RSpec.configure do |config|
  config.expect_with :rspec do |c|
    c.syntax = :expect
  end

  # ## Mock Framework
  #
  # If you prefer to use mocha, flexmock or RR, uncomment the appropriate line:
  #
  #config.mock_with :mocha
  # config.mock_with :flexmock
  # config.mock_with :rr

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

  # 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 = false

  # 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

Capybara.javascript_driver = :webkit

控制器测试:

require 'spec_helper'
include Devise::TestHelpers

describe PagesController do
  # This should return the minimal set of attributes required to create a valid
  # Page. As you add validations to Page, be sure to
  # update the return value of this method accordingly.
  def valid_attributes
    {  }
  end

  # This should return the minimal set of values that should be in the session
  # in order to pass any filters (e.g. authentication) defined in
  # PagesController. Be sure to keep this updated too.
  def valid_session
    {}
  end

  describe "GET index" do
    it "assigns all pages as @pages" do
      page = Page.create! valid_attributes
      get :index, {}, valid_session
      assigns(:pages).should eq([page])
    end
  end

  describe "GET show" do
    it "assigns the requested page as @page" do
      page = Page.create! valid_attributes
      get :show, {:id => page.to_param}, valid_session
      assigns(:page).should eq(page)
    end
  end

  describe "GET new" do
    it "assigns a new page as @page" do
      get :new, {}, valid_session
      assigns(:page).should be_a_new(Page)
    end
  end

  describe "GET edit" do
    it "assigns the requested page as @page" do
      page = Page.create! valid_attributes
      get :edit, {:id => page.to_param}, valid_session
      assigns(:page).should eq(page)
    end
  end

  describe "POST create" do
    describe "with valid params" do
      it "creates a new Page" do
        expect {
          post :create, {:page => valid_attributes}, valid_session
        }.to change(Page, :count).by(1)
      end

      it "assigns a newly created page as @page" do
        post :create, {:page => valid_attributes}, valid_session
        assigns(:page).should be_a(Page)
        assigns(:page).should be_persisted
      end

      it "redirects to the created page" do
        post :create, {:page => valid_attributes}, valid_session
        response.should redirect_to(Page.last)
      end
    end

    describe "with invalid params" do
      it "assigns a newly created but unsaved page as @page" do
        # Trigger the behavior that occurs when invalid params are submitted
        Page.any_instance.stub(:save).and_return(false)
        post :create, {:page => {  }}, valid_session
        assigns(:page).should be_a_new(Page)
      end

      it "re-renders the 'new' template" do
        # Trigger the behavior that occurs when invalid params are submitted
        Page.any_instance.stub(:save).and_return(false)
        post :create, {:page => {  }}, valid_session
        response.should render_template("new")
      end
    end
  end

  describe "PUT update" do
    describe "with valid params" do
      it "updates the requested page" do
        page = Page.create! valid_attributes
        # Assuming there are no other pages in the database, this
        # specifies that the Page created on the previous line
        # receives the :update_attributes message with whatever params are
        # submitted in the request.
        Page.any_instance.should_receive(:update_attributes).with({ "these" => "params" })
        put :update, {:id => page.to_param, :page => { "these" => "params" }}, valid_session
      end

      it "assigns the requested page as @page" do
        page = Page.create! valid_attributes
        put :update, {:id => page.to_param, :page => valid_attributes}, valid_session
        assigns(:page).should eq(page)
      end

      it "redirects to the page" do
        page = Page.create! valid_attributes
        put :update, {:id => page.to_param, :page => valid_attributes}, valid_session
        response.should redirect_to(page)
      end
    end

    describe "with invalid params" do
      it "assigns the page as @page" do
        page = Page.create! valid_attributes
        # Trigger the behavior that occurs when invalid params are submitted
        Page.any_instance.stub(:save).and_return(false)
        put :update, {:id => page.to_param, :page => {  }}, valid_session
        assigns(:page).should eq(page)
      end

      it "re-renders the 'edit' template" do
        page = Page.create! valid_attributes
        # Trigger the behavior that occurs when invalid params are submitted
        Page.any_instance.stub(:save).and_return(false)
        put :update, {:id => page.to_param, :page => {  }}, valid_session
        response.should render_template("edit")
      end
    end
  end

  describe "DELETE destroy" do
    it "destroys the requested page" do
      page = Page.create! valid_attributes
      expect {
        delete :destroy, {:id => page.to_param}, valid_session
      }.to change(Page, :count).by(-1)
    end

    it "redirects to the pages list" do
      page = Page.create! valid_attributes
      delete :destroy, {:id => page.to_param}, valid_session
      response.should redirect_to(pages_url)
    end
  end

end

错误:

失败:

  1) PagesController GET index assigns all pages as @pages
     Failure/Error: assigns(:pages).should eq([page])
     NoMethodError:
       undefined method `should' for #<Array:0x007fb986c42948>
     # ./spec/controllers/pages_controller_spec.rb:23:in `block (3 levels) in <top (required)>'

  2) PagesController POST create with valid params creates a new Page
     Failure/Error: expect {
       count should have been changed by 1, but was changed by 0
     # ./spec/controllers/pages_controller_spec.rb:53:in `block (4 levels) in <top (required)>'

  3) PagesController POST create with valid params assigns a newly created page as @page
     Failure/Error: assigns(:page).should be_a(Page)
     NoMethodError:
       undefined method `should' for nil:NilClass
     # ./spec/controllers/pages_controller_spec.rb:60:in `block (4 levels) in <top (required)>'

  4) PagesController POST create with valid params redirects to the created page
     Failure/Error: response.should redirect_to(Page.last)
     NoMethodError:
       undefined method `should' for #<ActionController::TestResponse:0x007fb987232c68>
     # ./spec/controllers/pages_controller_spec.rb:66:in `block (4 levels) in <top (required)>'

  5) PagesController POST create with invalid params assigns a newly created but unsaved page as @page
     Failure/Error: assigns(:page).should be_a_new(Page)
     NoMethodError:
       undefined method `should' for nil:NilClass
     # ./spec/controllers/pages_controller_spec.rb:75:in `block (4 levels) in <top (required)>'

  6) PagesController POST create with invalid params re-renders the 'new' template
     Failure/Error: response.should render_template("new")
     NoMethodError:
       undefined method `should' for #<ActionController::TestResponse:0x007fb986e1d1f0>
     # ./spec/controllers/pages_controller_spec.rb:82:in `block (4 levels) in <top (required)>'

  7) PagesController GET new assigns a new page as @page
     Failure/Error: assigns(:page).should be_a_new(Page)
     NoMethodError:
       undefined method `should' for #<Page:0x007fb982404708>
     # ./spec/controllers/pages_controller_spec.rb:38:in `block (3 levels) in <top (required)>'

  8) PagesController PUT update with valid params updates the requested page
     Failure/Error: put :update, {:id => page.to_param, :page => { "these" => "params" }}, valid_session
       #<Page:0x007fb9872517f8> received :update_attributes with unexpected arguments
         expected: ({"these"=>"params"})
              got: ({})
     # ./app/controllers/pages_controller.rb:61:in `block in update'
     # ./app/controllers/pages_controller.rb:60:in `update'
     # ./spec/controllers/pages_controller_spec.rb:96:in `block (4 levels) in <top (required)>'

  9) PagesController PUT update with valid params assigns the requested page as @page
     Failure/Error: assigns(:page).should eq(page)
     NoMethodError:
       undefined method `should' for #<Page:0x007fb981579a30>
     # ./spec/controllers/pages_controller_spec.rb:102:in `block (4 levels) in <top (required)>'

  10) PagesController PUT update with valid params redirects to the page
     Failure/Error: response.should redirect_to(page)
     NoMethodError:
       undefined method `should' for #<ActionController::TestResponse:0x007fb9827b7350>
     # ./spec/controllers/pages_controller_spec.rb:108:in `block (4 levels) in <top (required)>'

  11) PagesController PUT update with invalid params assigns the page as @page
     Failure/Error: assigns(:page).should eq(page)
     NoMethodError:
       undefined method `should' for #<Page:0x007fb987444a88>
     # ./spec/controllers/pages_controller_spec.rb:118:in `block (4 levels) in <top (required)>'

  12) PagesController PUT update with invalid params re-renders the 'edit' template
     Failure/Error: response.should render_template("edit")
     NoMethodError:
       undefined method `should' for #<ActionController::TestResponse:0x007fb982e75750>
     # ./spec/controllers/pages_controller_spec.rb:126:in `block (4 levels) in <top (required)>'

  13) PagesController GET show assigns the requested page as @page
     Failure/Error: assigns(:page).should eq(page)
     NoMethodError:
       undefined method `should' for #<Page:0x007fb9830f3a68>
     # ./spec/controllers/pages_controller_spec.rb:31:in `block (3 levels) in <top (required)>'

  14) PagesController DELETE destroy redirects to the pages list
     Failure/Error: response.should redirect_to(pages_url)
     NoMethodError:
       undefined method `should' for #<ActionController::TestResponse:0x007fb988100e98>
     # ./spec/controllers/pages_controller_spec.rb:142:in `block (3 levels) in <top (required)>'

  15) PagesController GET edit assigns the requested page as @page
     Failure/Error: assigns(:page).should eq(page)
     NoMethodError:
       undefined method `should' for #<Page:0x007fb9872585f8>
     # ./spec/controllers/pages_controller_spec.rb:46:in `block (3 levels) in <top (required)>'
4

1 回答 1

25

RSpec 提供了两种编写期望的方式:

  1. 应该风格1.should == 1
  2. 期待风格expect(1).to eq(1)

您的 spec_helper 配置为使用后者。将语法配置更改为:c.syntax = :should

参考:https ://www.relishapp.com/rspec/rspec-expectations/docs/syntax-configuration

于 2013-04-17T16:53:32.073 回答