views:

17

answers:

1

Guys,

Here is a model that I'm using, I've simplified it a bit down to the simplest form that still fails my example:

class User <  ActiveRecord::Base
  after_create :setup_lists

  def setup_lists
    List.create(:user_id => self.id, :name => "current")
    List.create(:user_id => self.id, :name => "master")
  end
end

And I'd like to spec the example as follows:

require 'spec_helper'

describe User do
  before(:each) do
    @user = Factory(:user)
  end

  describe "#setup_lists" do
    before(:each) do  
     List.stub(:create).with(:name => "current")
     List.stub(:create).with(:name => "master")

     it "creates a new master list" do
        List.should_receive(:create).with(:name => "master")
     end

     it "creates a new current list" do
        List.should_receive(:create).with(:name => "current")
     end
  end
end

Which I expected would work just fine, but I am left with the following error:

Failures:
  1) User#setup_lists creates a new master list
     Failure/Error: List.should_receive(:create).with(:name => "current")
     (<List(id: integer, name: string, created_at: datetime, updated_at: datetime, user_id: integer) (class)>).create({:name=>"current"})
      expected: 1 time
      received: 0 times
    # ./spec/models/user_spec.rb:44

  2) User#setup_lists creates a new current list
     Failure/Error: List.should_receive(:create).with(:name => "master")
     (<List(id: integer, name: string, created_at: datetime, updated_at: datetime,        user_id: integer) (class)>).create({:name=>"master"})
     expected: 1 time
     received: 0 times
  # ./spec/models/user_spec.rb:48

Can anybody help me understand why this is happening?

THanks,

Joe

A: 

Three issues:

1) The User object is created before setting the message expectation, so should_receive never gets to see the message;

2) You're stubbing out methods for which you're also setting expectations. You want to stub out methods for which you don't set expectations, but which are needed for the test to pass

3) You need to pass in all the parameters

To fix, create the User object after setting the expectaion, and stub out each method in turn (because your model calls List.create twice):

describe User do
  describe "#setup_lists" do
    it "creates a new master list" do
      List.stub(:create).with(:user_id=>1,:name => "current")
      List.should_receive(:create).with(:user_id=>1,:name => "master")
      @user = User.create
    end

    it "creates a new current list" do
      List.stub(:create).with(:user_id=>1,:name => "master")
      List.should_receive(:create).with(:user_id=>1,:name => "current")
      @user = User.create
    end
  end
end

While it's really an issue of style, it makes more sense to use a real User object here rather than a factory, since you're testing the model itself.

zetetic