2016-03-08 198 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