Thank you for your answers! > In The Rspec Book, section 24.6 (chapter 24), "When I write view specs" offers some tips for determining when to write view specs. Have you read this section?
I though I did, but I revisited it and I learned some new things. Thanks! I did some thinking on my own and I reached some conclusions. I would like to share them -- it will help me structure my reasoning. I would be happy to hear what you think. This is going to be long. I'm assuming that I want to use test doubles in view specs. I don't see much value in testing model, view and helper code at once. Also, I'm only checking for the presence of text and occasionally for the presence of a link. I'm not asserting DOM structure or rendering order. There is a big difference between using doubles in controller specs and in view specs. Controllers depend only on the models. Using test doubles in their specs leads you to a nice, clean public interface of the models and only a handful of simple messages in the actions. The code is just a simple moderator. This is what a clean controller should be, in my opinion. Views, on the other hand, know a lot of tiny details about the models. After all, they should if they are to present that information in a humane way. Thus, they are more coupled to the models than controllers. This requires more intricate test doubles. Furthermore, they also invoke helpers to do some of the work. Not only you have to mock them too, but most of the time helpers just take a model and return a result dependent on it. This is tricky to mock (simplest case you make a mock of the model and set an expectation on a helper). That's two problems with test doubles in view specs -- (1) view and model is more tightly coupled and (2) you have helpers as a depend-on component. At this point, getting the test doubles right is too much work. The usual problem that I have, is that as soon as I complete a refactoring in the model, I have to spend an equal (or even greater) effort to fix the doubles in spec failures, that are false negatives. I think I've seen this named 'fragile test'. Thus, my approach would be to avoid writing view specs most of the time and make sure I've provided the safety net with Cucumber. That is my case against view specs. I can see two reasons to write them, though. First, I can consider it as purchasing technical debt. I write a view spec instead of a Cucumber scenario for a small behavior modification. This gives me the safety net for a lower price (view specs take considerably less time), but the cost is that it hinders refactoring. Second, if I have something complex to display and no idea now to organize it, I can use a view spec to drive the design. This let's me base it on feedback, but when I've implemented the functionality back-to-back, the view spec has turned into an expensive artifact that hinders further refactoring. I've done that a few times -- it really helps me with the design, but I find myself removing the spec after a while since it takes just too much time to maintain. I also see two things that might invalidate this reasoning. First, presenters. They group the model and helpers logic that the view depends on, so now I would have to mock only one object. More importantly, that object is specifically designed to be used by the view, which means that the test double will be simple and that I can use the view spec to drive the design of the presenter. Second, moving all logic from the view to helpers that take the model as a parameter. This should simplify the test doubles, although you still will have to set expectations on helper invocations. This moves the intricate knowledge of the models in the helpers, which are easier to test. The view mediates models and helpers. I'm not sure if I like the resulting design. While the views look slick, you have to understand the helpers first in order to understand the view. Logic that belongs together is scattered around in multiple files, intermingled with other logic. Also, at this point I don't see much reason to write a view spec either, since the code that could possibly break is either in models or helpers, which are tested in isolation. If you insist on doing it, setting up test doubles is still a bit weird (you have to set expectations and define results on helpers and you have to use mocks for models). It gets particularly tricky when the view iterates over a collection and calls a few helpers with each item. On the more general note, while controllers are pretty OO in they nature and thus can tolerate test doubles, views are, well, just procedural Ruby embedded in HTML. Applying mocks to them doesn't seem a good fit to me. So, what do you think? Does this make sense? Did I miss anything?
_______________________________________________ rspec-users mailing list rspec-users@rubyforge.org http://rubyforge.org/mailman/listinfo/rspec-users