Nekron
Nekron

Reputation: 123

Why my rspec test fail?

I'm writing a test for my ShowcasesController, and I'm stuck in "GET new" action, for sign in user.

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

For unknown reason, my test fail and I'm reciving this error massage:

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

Upvotes: 0

Views: 63

Answers (2)

BroiSatse
BroiSatse

Reputation: 44715

There is no showcase method defined on your controller, there is only an instance variable.

To check instance variables on the controller, rspec controller test provides assigns function:

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

Note: As far as I am aware, there are currently some plans to remove assigns from rspec. I believe that the decision is made because it violates "don't test private implementation details" - I personally dislike this decision a lot, as it will make controller unit testing much harder. IMO, Even though it is instance variable, it is being used to communicate between controller and a view and as such is part of controller public API. (Putting on side that using instance variables for public API sucks as hell).

Upvotes: 4

gnerkus
gnerkus

Reputation: 12037

The error occurs because the method showcase has not been defined for the ShowcasesController. More precisely, an accessor has not been defined for the showcase property of the controller.

An example with an accessor
class ShowcasesController
  attr_accessor :showcase

  # other controller methods
end

Upvotes: 0

Related Questions