David Schmidt wrote:
> 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

I was going to start a thread about mocks and fixtures this morning too, so Ill 
use this one.

Let me first say that I am a very very recent comer to RSpec so my opinions 
dont 
carry much weight, but ...

I have come to the tentative conclusion that mocking is fine in view specs 
where 
you are really only interested that certain assigns have been made and that 
they 
respond to certain messages. In fact mocks are ideal. Possibly in models too. 
However in controller specs I think you find examples where fixtures are just 
the best way to go. In these cases, from what I have seen, mocking leads to 
brittle and frankly worthless tests (a half-arsed test is worse than no test at 
all, right?).

The case that crystalised that opinion for me was a spec for a destroy action. 
In spec::rails scaffold (and in many examples I see online) this action is 
tested by asserting that the instance receives a destroy message. I personally 
think thats inadequate. It makes assumptions about implementation and doesnt 
guard against unwanted side effects.

I should be able to delete a record any way I please (delete, destroy, 
connection().execute(...)) and the test should pass. This is BDD after all. We 
should be testing the behaviour of the action, not the implementation, and the 
desired behaviour is that the corresponding record *and only that record* are 
deleted ... no one cares how its achieved. The only correct way to test this 
IMHO is to assert that TheModel.find(:all) before the action is equal to 
TheModel.find(:all) after the action less the record in question. For this I 
see 
fixtures as the way to go.

Just my opinion. Commence flaming.
_______________________________________________
rspec-users mailing list
rspec-users@rubyforge.org
http://rubyforge.org/mailman/listinfo/rspec-users

Reply via email to