Hello fellow RSpec users.

Before you all start warming up your flame throwers please let me explain my Subject line.

I've been working over 4 months on a large Rails project with a few other developers. Test coverage was spotty at best, though they *were* RSpec tests. One of the other developers and I had started adding more tests, mostly controller tests using the methodology given at rspec.info for writing controller tests isolated from the model and view layers using stubs and mocks.

Recently a new project manager was put in place and he brought in another developer. This developer promptly started to re-write all the *existing* controller (and later view) tests, removing all mocks and stubs and replacing them with code to use fixtures. (He also deletes many comments he finds in the code if *he* thinks they're obvious, but that's another story...). His commit messages include comments like "Stop mocking around" and "More fixes due to our test mockery".

When challenged on why he's re-writing these tests instead of writing new, missing tests (even tests using fixtures) he replied with this e- mail with the subject "Why not MockEverything". (Note that I *do* use fixtures for model tests but follow the RSpec documentation and use mocks/stubs for controller and view tests for isolation.) In the email this developer mentions tests broken by the addition of conditional to the view. This conditional used a model method not previously used in the view, and the addition of one stub was sufficient to fix the view test in question.

Here is his email to me, less his signature as I don't want to make this personal. I'd like to see what the RSpec user community has to say in response to his comments, below:

--- Why not MockEverything ---
David I've removed the mocks on purpuse. Not that I have sufficient ills with them to meddle without a *need*. We committed simple template fixes adding a conditional and there, yet the tests broke.

Now this was to be expected, the tests were constructed by exhaustively mocking out all methods called on the object. Add a simple conditional be it harmless as it is now means another method needs to be mocked out.

The MockEverything approach is not healthy, judicious use is preferable. One thing is to write a short sample in a blog and another is to have a working app with lots of tests. From all my apps that I have worked on this has by far the lowest coverage both in profile and in test value. There is no discussion we are all committed to tests.

To better see what constitutes good practice I recommend you to inspect the source of RadiantCMS a beautiful and well engineered app recently rewrote to use rspec instead of Test::Unit:

http://dev.radiantcms.org/browser/trunk/radiant/spec

Observe how the code is restrained in mocking, real objects are preferred wherever possible. Incidentally they don't use fixtures rather factories to create *real* objects. Now the factory part is a separate issue I'll don't discuss here, as it has its own disadvantages especially a project with many models ...

With real objects your test will not be brittle, and their value will be kept even after adjusting the templates or doing other small refactorings. Contrary to common misconception test speed will not be affected either. Especially for view tests where you don't even have to save to the db upon preparing the test rig.

Beside Radiant there where efforts to rspec Typo and Mephisto (both noted rails blog engines). Still these were half harted conversions so my arguments based on them would not have the same weight. RadiantCMS is enough - they are used on ruby-lang.org and have converted 100% to rspec ... plus they also have good coverage showing that they actually believe in tests. So please look into Radiant, you'll find it most helpful I think.
--- END OF EMAIL---

Thank you,

David Schmidt

_______________________________________________
rspec-users mailing list
rspec-users@rubyforge.org
http://rubyforge.org/mailman/listinfo/rspec-users

Reply via email to