eayurt
eayurt

Reputation: 1177

Rails 3 RSpec controller testing Failure/Error:

I am testing my Rails 3.2 app and I faced an error when I tried to test my controller.

This is my controller

class WidgetsController < ApplicationController
  #skip_before_filter :authenticate, :only => [:new, :create]
  before_filter :authenticate, :except=>[:disabled]

  def index
    @widgets = current_user.widgets.all
    respond_to do |format|
      format.html # index.html.erb
      format.json { render json: @widgets }
    end
  end

  def new
    @widget = Widget.new
  end

  def create
    @widget = Widget.new(params[:widget])
    @widget.user_id = current_user.id
    @widget.score = 0
    @widget.total_score = 0
    @widget.click_number = 0
    @widget.average = 0
    respond_to do |format|
      if @widget.save
        format.html { redirect_to edit_widget_path(@widget), notice: 'Widget was successfully created.' }
        format.json { render json: @widget, status: :created, location: @widget }
      else
        format.html { render action: "new" }
        format.json { render json: @widget.errors, status: :unprocessable_entity }
        raise 'there is an error when creation'
      end
    end
  end

  def show
    @widget = Widget.find_by_uuid(params[:uuid])
  end

  def edit
    @widget = Widget.find_by_uuid(params[:uuid])
  end

  def update
    @widget = Widget.find_by_uuid(params[:uuid])
    respond_to do |format|
      if @widget.update_attributes(params[:widget])
        format.html { redirect_to edit_widget_path(@widget), notice: 'Widget was successfully updated.' }
        format.json { render json: @widget, status: :created, location: @widget }
      else
        format.html { render action: "edit" }
        format.json { render json: @widget.errors, status: :unprocessable_entity }
      end
    end
  end

  def destroy
    @widget = Widget.find_by_uuid(params[:uuid]).destroy
    redirect_to widgets_path
  end

  #generate widget
  def generate
    respond_to do |format|
      format.js {}
    end
  rescue
    #TODO add widget not found page
    render :template => 'application/widget_not_found', :status => :not_found
  end



  protected

  def authenticate
    unless current_user
      redirect_to root_url
    end
  end

end

This is my controller spec

require 'spec_helper'

describe WidgetsController do
  login_admin

  describe "User" do
    it "should have a current_user" do
      subject.current_user.should_not be_nil
    end
  end

  def mock_widget(stubs={})
    @mock_widget ||= mock_model(Widget, stubs).as_null_object
  end

  describe "GET index" do
    it "assigns all widgets as @widgets" do
      Widget.stub(:all) { [mock_widget] }
      get :index
      assigns(:widgets).should eq([mock_widget])
    end
  end

end

I just want to see that I can get data on index page. However I have seen this error on command line when I run $rspec spec/controllers/widgets_controller_spec.rb

.F

Failures:

  1) WidgetsController GET index assigns all widgets as @widgets
     Failure/Error: assigns(:widgets).should eq([mock_widget])

       expected: [#<Widget:0x3ffb0c3c9d70 @name="Widget_1001">]
            got: []

       (compared using ==)

       Diff:
       @@ -1,2 +1,2 @@
       -[#<Widget:0x3ffb0c3c9d70 @name="Widget_1001">]
       +[]
     # ./spec/controllers/widgets_controller_spec.rb:20:in `block (3 levels) in <top (required)>'

Finished in 0.11937 seconds
2 examples, 1 failure

Failed examples:

rspec ./spec/controllers/widgets_controller_spec.rb:17 # WidgetsController GET index assigns all widgets as @widgets

I did this tutorial http://www.codethinked.com/rails-3-baby-steps-part-4 and I did not face with any problems. How should I fix it? What does this error mean?

Upvotes: 0

Views: 1086

Answers (1)

Steve Rowley
Steve Rowley

Reputation: 1578

I'd guess it has something to do with scoping the set of widgets returned by current_user in the controller. In the controller you are calling the all method on a collection of widget objects (instances of the Widget class), and in the test you are stubbing the all method of the Widget class. You can test this theory by changing you controller method to simply call Widget.all. I know that isn't what you want it to do, but it will confirm this is the problem.

Upvotes: 1

Related Questions