I'm working through an rspec tutorial (peepcode tutorial). I generated some scaffold and I was hoping someone can help explain how the describe could be re-written to read a bit clearer for newbie.
describe "POST create" do
describe "with valid params" do
it "assigns a newly created weather as @weather" do
Weather.stub(:new).with({'these' => 'params'}) { mock_weather(:save => true) }
post :create, :weather => {'these' => 'params'}
assigns(:weather).should be(mock_weather)
end
end
This line of code is what I'm trying to understand is this one
Weather.stub(:new).with({'these' => 'params'}) { mock_weather(:save => true) }
I have never seen a method being put inside braces. What does this actually mean?
{ mock_weather(:save => true) }
As for your first question about "how to make it a bit clearer", we could begin by not using mocks.
A mock object is useful when you can not depend on a predictable behavior of a secondary object, an object that is not important but must be present in your test case. Typical examples of the usage of mock objects are database queries, network usage, file i/o. You don't want your tests to fail because your computer lost network connection, or a database is not available.
The generated code that you got from the
rails g scaffold
is not optimal. The generated code was generated in a way that will make all tests pass, and for that it uses mock objects. I don't know why they do that, I think a better default would be failing tests so that you actually need to do something to make them pass.I would delete the generated mocks and do something like the following:
Notice that we are not using mock objects, and so the code is reduced to making the POST call with some parameters and verifying that object is valid. Since will have to write the validation rules in your model file, and you are not using a mock object, you can be sure that an actual validation is going on.
With the auto generated mock files you don't have to do anything at all and the tests will continue to pass forever. That is a bad idea, and bad practice.
Also notice that you should write more tests that exercise the cases where there are invalid or missing parameters. And again, by doing
assigns(:weather).should_not be_valid
you are verifying that your validations are doing their job.Writing the dictionary of parameters every time you call
post :create
is repetitive, fragile and ugly. You should study how to use fixtures. For example, with Factory GirlThat gives you reusable and more readable code.