On Mar 19, 2008, at 8:42 AM, Glenn Ford wrote:
> My primary concern when writing my specs that are to cover complicated
> features is that I do NOT want false confidence. If I write a spec,
> and it passes, I want that to mean it works in my app. When the spec
> goes green, my next step is to go hit Refresh in my browser. If it
> doesn't work in my browser, then in my opinion, my spec is crap. It's
> telling me things work when they don't.
This paragraph caught my eye, especially in my specific issue of mocks/
stubs versus fixtures in our own tests.
In my view tests I use mock_model with a hash of valid attributes.
This allows a mock with automatic stubs for these valid attributes:
valid_user_attributes = {
'name' => 'user name',
'userid' => 'userid'
}
before (:each) do
@mock_user = mock_model(User, valid_user_attributes)
[...]
end
A sample test to verify that one of these attributes is properly
displayed looks like:
it "should display the user name in the contact box" do
do_render
response.should have_tag('div#contact', /[EMAIL PROTECTED]/)
end
The dev that wants all fixtures does this by loading a fixture record:
before (:each) do
user = User.find( users(:david).id )
[...]
end
His tests written to check that particular attributes were properly
displayed in the view look like:
it "should display the user name in Contact Pod" do
do_render
response.should have_tag('div#contact', /^#{users(:david).name}/)
end
This developer added some new code to the view in question, displaying
a new table value and complained when my mock/stub version of the test
failed because there was no stub to display that new attribute.
However, though his test passed, he had failed to add the "name"
attribute to his fixtures. This meant that users(:david).name was
returning an empty string ('') and his test was just checking that an
empty string was in the view output, which would pass EVERY time!
I demonstrated this by putting an 'X' after each of the names in the
regex (like /[EMAIL PROTECTED]/) to force a failure. When I ran
both versions of the test I saw the following output for my test:
</.*User NameX.*/> expected but was <"User Name\n 123 Any St....
The fixtures version of the test with the 'X' returned this error:
</^X/> expected but was <"User Name\n \n \n...
Note that nothing is showing prior to the X, because name wasn't in
the fixture. My point is that was much easier to forget to add the
new attributes to the fixtures in another file. When adding the new
attribute to the valid_user_attributes you'd have to create it as an
empty string ('name' => '') which would be much less likely to happen.
With the fixtures version pulling data from the fixtures files it's
much less obvious when you have bad data in the fixture. As far as
maintenance, the mock/stub version only required one line to be added
to the valid_user_attributes hash. The fixtures version requires that
new attribute to be added to every fixture that will be using that
attribute and it's easy to accidently leave it out of some fixture
records.
The result, at least in *this* particular case, is that it was much
easier to end up with a number of tests returning false "passes" using
the fixtures method.
I'm not a 100% mock/stub proponent, but I'm very much against 100%
fixtures and like using mocks and stubs for view tests where what you
are testing is that the proper data is displayed in the correct
containers in the view.
David
_______________________________________________
rspec-users mailing list
[email protected]
http://rubyforge.org/mailman/listinfo/rspec-users