[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