[rspec-users] When to use Factories, Mock Models, Mocks & Stubs

Frank Lakatos me at franklakatos.com
Tue Feb 2 19:00:25 EST 2010


Hi guys, been following for about 3 weeks, first question -

I've been spending the last couple of months learning RSpec and  
Cucumber and I'm just finally starting to see the "big picture", at  
least I think I am. But I've got some questions I was hoping you guys  
can clear up. I'm sure this has been asked a lot, so please bare with  
me. Just let me know when my logic is wrong or when I'm way off  
course. You guys have been a kind group, so I'm not to concerned with  
sounding foolish.

I've been using .should_receive and .stub to let my spec know that my  
controller is going to be making a method call. I know .should_receive  
will fail when you don't call that method (or if you call it more  
times than you said you would) and I use stub when It's going to get  
called an unpredictable amount of times, like in a before block. To  
me, it sounds like I don't really know what the difference is, and I  
just have some understanding of there symptoms.

When i need to talk about a model, I usually use mock_model. I have  
Factory_girl, but I've heard that you should be careful when using  
Factory girl, as it ties you down to the requirements of the  
attributes, and not the overall functionality (although, that  
statement may not be true in itself). So normally, I use Factories in  
Cucumber, as that is concerned with more higher level usage features,  
and mock_models for controller/model specs.

Alot of times, however, I feel like I'm doing way to much work to get  
the whole thing working. Maybe I am, maybe I'm not, only way is to  
show off what I'm doing.

app/controller/projects_controller#create

   def create
       @client = current_user.company.clients.find(params[:project] 
[:client_id])
       @project = @client.projects.build(params[:project])
       if @client.save
         flash[:notice] = "Added: #{@project.name}"
       else
         render :new
       end
   end


spec/controller/projects_controller_spec

describe ProjectsController do
     describe "POST 'create'" do

     before do
       @current_user = mock_model(User)
       controller.stub(:current_user).and_return @current_user
       @company = mock_model(Company)
       @current_user.should_receive(:company).and_return @company
       @clients = mock("Client List")
         @company.should_receive(:clients).and_return @clients
     end

     describe "when client is found" do

       before do
         @client = mock_model(Client)
         @clients.should_receive(:find).and_return @client
       end

       describe "on successful save" do

         before do
           @projects = mock_model(ActiveRecord)
           @client.should_receive(:projects).and_return @projects
           @project = mock_model(Project)
           @projects.should_receive(:build).and_return @project
           @client.should_receive(:save).and_return true
           @project.should_receive(:name).and_return "New Project"
         end

         it "should set up the flash" do
           post "create", {:project => {:client_id => 1}}
           flash[:notice].should_not be_nil
         end

        end

     end

   end


end


Let me know how it sounds, and it looks like I'm doing so far

Thanks,
Frank











More information about the rspec-users mailing list