[rspec-users] rspec 1 - nested examples (in an each block) use the final block variable 4 times instead of each of the 4 once

nruth nick.rutherford at gmail.com
Fri Jul 30 21:08:39 EDT 2010


Hi Ash

I've found let and before useful in different situations. I like let
as a 'new feature' but am not sure it replaces, or is necessarily
superior to, @vars in all cases for specs.

If I want to set up a context to run some examples in (models created
with machinist, associations, etc) then the before block makes it
clear that that's the state the examples are running against, and the
@vars give me a (quick and dirty?) hook to refer back to parts of that
setup (e.g. associated models) in the spec examples.

Of course, this can be done with let as well, but since they are lazy-
evaluated you can end up with your examples running in the wrong
context. For example: http://gist.github.com/501517

So after falling in love with let I've found sometimes it isn't worth
the overhead & it's just quicker and tidyer to use before/@ ? I wonder
whether in the end the only difference is the syntax highlighting,
couple of extra lines of code or @ character, and perhaps the time /
thought process in getting there.

back to op briefly, I ended up with this approach for the specs
instead:

  describe "#add_question_set_of_type('Abstract Reasoning')" do
    let(:subtest) {'Abstract Reasoning'}
    it_should_behave_like "adding a question set"
  end

  describe "#add_question_set_of_type('Decision Analysis')" do
    let(:subtest) {'Decision Analysis'}
    it_should_behave_like "adding a question set"
  end

etc…

perhaps not ideal if another test is added in later, and I wanted
coverage of that too for free, but it avoided the immediate problem &
is more clear what's going on.

I certainly prefer let and subject to @vars for shared examples -
again both work, but I find subject & lets provide a clear interface
for the shared example groups which I felt was lacking when passing
@variables around.

Re: error / warning message, at the same scope (i.e. an accident, as
in the op) then yes that could be quite useful for spotting mistakes.
I'm not so sure about in different blocks though, it's probably
intentional there (different context).

Re: redefining vs refactoring - I like what you're saying (reminds me
of dry vs non-dry specs, and I find myself refactoring a lot of my old
spaghetti specs lately), but wonder if there are (edge) cases where
it's useful or necessary. Maybe there's some discussion dating back to
when the feature was added. It may be stylistic though, rather than
enforceable?

Re: LSP, food for thought, nothing to add at present unfortunately.
Not sure what angle you're approaching shared examples from with that
though, do you mean redefining lets inside of the shared example
groups, or something else?

Cheers,
Nick

On Jul 30, 11:13 pm, Ashley Moran <ashley.mo... at patchspace.co.uk>
wrote:
> On 30 Jul 2010, at 10:00 PM, nruth wrote:
>
> >http://gist.github.com/501296
>
> > I don't think anything needs to change, though a wrapper function
> > (each + an inner describe) might help flag it as a possible pitfall.
>
> Hi Nick
>
> I think the "before + ivar" pattern (below) is on its way out.  At least, I consider it deprecated in my head:
>
>   describe "before" do
>     before(:each) { @foo = "bar" }
>     before(:each) { @foo = "baz" }
>
>     it "does this" do
>       @foo.should eq "baz"
>     end
>   end
>
> But the new syntax does indeed let you redefine `let` blocks.
>
>   describe "let" do
>     let(:foo) { "bar" }
>     let(:foo) { "baz" }
>
>     it "does this (currently)" do
>       foo.should eq "baz"
>     end
>   end
>
> Arguably, this is not the most desirable behaviour, as it leads to silent/confusing failures, as you've seen.  Maybe it would be better if this raised an error?  (Which is only an option with `let`, not with ivars.)
>
> Also, when combined with shared examples, this could conceivably be used to violate the Liskov Substitution Principle (if the LSP applies to specs).  While Ruby as a language lets you redefine stuff at will, I'm not sure that's appropriate here.  I can't imagine wanting to redefine a let, instead of factoring it out properly.  Anyone got any thoughts on that?
>
> Ash
>
> --http://www.patchspace.co.uk/http://www.linkedin.com/in/ashleymoran
>
> _______________________________________________
> rspec-users mailing list
> rspec-us... at rubyforge.orghttp://rubyforge.org/mailman/listinfo/rspec-users


More information about the rspec-users mailing list