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

me at franklakatos.com me at franklakatos.com
Wed Feb 3 09:52:16 EST 2010


Ok, so these ideas seem kind of natural to me, which is nice:

mock_models being used to mock non-tested models
stub for queries and/or well-tested methods, should_receives for commands

While reading over Dave Astlels, I kind of got concerned because of  
something he states that I feel I'm doing in my specs:

"When you realize that it's all about specifying behaviour and not  
writing tests, your point of view shifts. Suddenly the idea of having  
a Test class for each of your production classes is ridiculously  
limiting. And the thought of testing each of your methods with its own  
test method (in a
1-1 relationship) will be laughable."

This is what I am striving for, but being guided simply by rSpec error  
messages results me in writing specs like this...

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



... for a controller that looks like this ...


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



Am I doing the 1-1 thing that BDD specifically set out to avoid?









Quoting Adam Sroka <adam.sroka at gmail.com>:

> On Tue, Feb 2, 2010 at 9:53 PM, Andrei Erdoss <erdoss at gmail.com> wrote:
>> Hello Frank,
>>
>> From my understanding these are the roles of should_receive and stub.
>>
>> should_receive checks to make sure that a method or a property is called. To
>> this you can specify the arguments that it gets called (.with()), what it
>> returns (.and_return) and how many times this happens (.once, .twice etc).
>>
>> stub on the other hand is a place holder for functions calls that have been
>> tested already or are Rails defaults, which don't need to be tested. stubs
>> are used in conjunction with mock_models, in order to provide for the
>> functions or properties that are needed for the code to run, up to the test
>> point.
>>
>
> I think that it is best to think of these in terms of command query
> separation. In case you aren't familiar with that principle, it states
> that some methods are commands - they tell an object to do something
> but don't return anything interesting, and other methods are queries -
> they return some interesting value but have no side effects.
>
> should_receive is how we set an expectation for a command. We don't
> really care what a command returns but we do care that it gets called.
> should_receive literally says that the command should be called with
> the given parameters.
>
> stub is how we handle a query. We care what a query returns, or rather
> the code we are testing does, but we don't really care when it gets
> called (or how often) per se. If we depend on its result then it
> should be called, but the effect that the result has on the system
> we're testing is what we really care about.
> _______________________________________________
> rspec-users mailing list
> rspec-users at rubyforge.org
> http://rubyforge.org/mailman/listinfo/rspec-users
>





More information about the rspec-users mailing list