2016-03-08 182 views
0

我正在爲我的ShowcasesController編寫一個測試,並且我陷入了「獲取新的」操作,登錄用戶。爲什麼我的rspec測試失敗?

require 'rails_helper' 
require 'spec_helper' 

RSpec.describe ShowcasesController, type: :controller do 

    context "user is signed in" do 

    before do 
     @user = create(:user) 
     @admin = create(:admin) 
     @showcase = create(:showcase) 
     @request.env["devise.mapping"] = Devise.mappings[:user] 
     sign_in(@user) 
    end 

    describe "GET new" do 
     context "user is not admin" do 
     it "redirect to root page" do 
      get :new 
      expect(response).to redirect_to(root_url) 
     end 
     end 

     context "user is an admin" do 
     it "expose a new showcase" do 
      sign_in(@admin) 
      get :new 
      expect(controller.showcase).to be_a_new(Showcase) 
     end 
     end 
    end 
    end 
end 

對於未知的原因,我的測試失敗,我reciving此錯誤按摩:

Failures:

1) ShowcasesController user is signed in GET new user is an admin expose a new showcase Failure/Error: expect(controller.showcase).to be_a_new(Showcase)

NoMethodError: 
    undefined method `showcase' for #<ShowcasesController:0x00000004d7c400> 
# ./spec/controllers/showcases_controller_spec.rb:104:in `block (5 levels) in <top (required)>' 
class ShowcasesController < ApplicationController 
    before_action :authenticate_user!, only: [:new, :create, :edit, :update, :destroy] 
    before_action :correct_user, only: [:new, :edit, :update, :destroy] 

    def index 
    @showcases = Showcase.all 
    end 

    def show 
    @showcase = Showcase.find(params[:id]) 
    end 

    def new 
    @showcase = Showcase.new 
    end 

    def create 
    @showcase = Showcase.new(showcase_params) 
    if @showcase.save 
    end 
    end 

    def edit 
    @showcase = Showcase.find(params[:id]) 
    end 

    def update 
    @showcase = Showcase.find(params[:id]) 
    if @showcase.update_attributes(showcase_params) 
    end 
    end 

    def destroy 
    @showcase = Showcase.find(params[:id]).destroy 
    end 

    private 

    def showcase_params 
    params.require(:showcase).permit(:first_name, :last_name, :sport_club, :email, :pass_exam_date, :pass_exam_location, 
    :exam_type, :level, :first_graduation_date, :second_graduation_date, :third_graduation_date, :fourth_graduation_date, 
    :total_match_number, :match_number_in_last_season) 
    end 

    def correct_user 
    unless current_user.admin? 
     redirect_to root_url 
    end 
    end 
end 
+0

您可以發佈控制器的代碼嗎? – gnerkus

+2

我想你的意思是'分配(:showcase)'而不是'controller.showcase'?僅僅因爲你設置了實例變量並不意味着它可以通過讀者訪問。最重要的是,你可能想要清理你的'before'塊,並使用'let'多一點,以避免測試中不必要的數據庫操作。 – BroiSatse

+0

現在,它的工作。不幸的是,我正在使用過時的教程。現在我要用你的建議重構我的代碼。你可以把你的答案作爲單獨的答案,所以我可以接受這是適當的答案? – Nekron

回答

4

還有就是你的控制器上沒有定義showcase方法,只有一個實例變量。

要檢查控制器的實例變量,RSpec的控制器測試提供assigns功能:

expect(assigns :showcase).to be_a_new(Showcase) 

注:據我所知,目前有一些計劃從rspec的去除assigns。我認爲做出這個決定是因爲它違反了「不測試私有實現細節」 - 我個人很不喜歡這個決定,因爲它會使控制器單元測試更加困難。 IMO,即使它是實例變量,它也被用來在控制器和視圖之間進行通信,因此是控制器公共API的一部分。 (把公共API的實例變量用作地獄)。

+0

(把公共API的實例變量視爲地獄)< - 是的! – jvillian

0

發生該錯誤是因爲尚未爲ShowcasesController定義方法showcase。更確切地說,控制器的showcase屬性尚未定義訪問器。

An example with an accessor 
class ShowcasesController 
    attr_accessor :showcase 

    # other controller methods 
end