views:

389

answers:

2

I have two models:

class Solution < ActiveRecord::Base
  belongs_to :owner, :class_name => "User", :foreign_key => :user_id
end                  

class User < ActiveRecord::Base
  has_many :solutions
end

with the following routing:

map.resources :users, :has_many => :solutions

and here is the SolutionsController:

class SolutionsController < ApplicationController
  before_filter :load_user

  def index
    @solutions = @user.solutions
  end

  private
    def load_user
      @user = User.find(params[:user_id]) unless params[:user_id].nil?
    end
end

Can anybody help me with writing a test for the index action? So far I have tried the following but it doesn't work:

describe SolutionsController do
  before(:each) do
    @user = Factory.create(:user)
    @solutions = 7.times{Factory.build(:solution, :owner => @user)}
    @user.stub!(:solutions).and_return(@solutions)
  end

  it "should find all of the solutions owned by a user" do
    @user.should_receive(:solutions)
    get :index, :user_id => @user.id
  end
end

And I get the following error:

Spec::Mocks::MockExpectationError in 'SolutionsController GET index, when the user owns the software he is viewing should find all of the solutions owned by a user'
#<User:0x000000041c53e0> expected :solutions with (any args) once, but received it 0 times

Thanks in advance for all the help.

Joe

EDIT:

Thanks for the answer, I accepted it since it got my so much farther, except I am getting another error, and I can't quite figure out what its trying to tell me:

Once I create the solutions instead of build them, and I add the stub of the User.find, I see the following error:

NoMethodError in 'SolutionsController GET index, when the user owns the software he is viewing should find all of the solutions owned by a user'
undefined method `find' for #<Class:0x000000027e3668>    
A: 

It's because you build solution, not create. So there are not in your database.

Made

  before(:each) do
    @user = Factory.create(:user)
    @solutions = 7.times{Factory.create(:solution, :owner => @user)}
    @user.stub!(:solutions).and_return(@solutions)
  end

And you mock an instance of user but there are another instance of User can be instanciate. You need add mock User.find too

  before(:each) do
    @user = Factory.create(:user)
    @solutions = 7.times{Factory.create(:solution, :owner => @user)}
    User.stub!(:find).with(@user.id).and_return(@user)
    @user.stub!(:solutions).and_return(@solutions)
  end
shingara
A: 

I figured out my edit, when a find is done from the params, they are strings as opposed to actual objects or integers, so instead of:

User.stub!(:find).with(@user.id).and_return(@user)

I needed

User.stub!(:find).with(@user.id.to_s).and_return(@user)

but thank you so much shingara you got me in the right direction!

Joe

TheDelChop