[rspec-users] shared behav

David Chelimsky dchelimsky at gmail.com
Tue Dec 18 17:31:01 EST 2007


On Dec 18, 2007 4:25 PM, David Chelimsky <dchelimsky at gmail.com> wrote:
>
> On Dec 18, 2007 4:22 PM, Scott Taylor <mailing_lists at railsnewbie.com> wrote:
> >
> >
> > On Dec 18, 2007, at 5:12 PM, David Chelimsky wrote:
> >
> > > On Dec 18, 2007 3:53 PM, Scott Taylor
> > > <mailing_lists at railsnewbie.com> wrote:
> > >>
> > >>
> > >> On Dec 18, 2007, at 4:42 PM, David Chelimsky wrote:
> > >>
> > >>> On Dec 18, 2007 3:37 PM, Scott Taylor
> > >>> <mailing_lists at railsnewbie.com> wrote:
> > >>>> The
> > >>>> shared behaviours can be thought of modules which are included
> > >>>> into the
> > >>>> current behaviour - so it should also have access to any methods
> > >>>> defined in
> > >>>> the example (group) in which it is shared.
> > >>>
> > >>> You don't even have to think of it that way - that's actually what
> > >>> they are - modules that get included. You can actually assign
> > >>> them to
> > >>> a constant and just use Ruby include.
> > >>
> > >> Although we've talked about the implementation changing, which would
> > >> cause those who use them as modules to have broken specs.
> > >
> > > It would, but we stopped talking about it :)
> > >
> > > It actually works quite well this way. The change came up, iirc, in
> > > the conversation about parameterizing it_should_behave_like, right?
> > > I've got a solution for that worked out, but I haven't applied it yet
> > > because I want to discuss it a bit:
> > >
> > > You'd use it like this:
> > >
> > > shared_examples_for "anything" do
> > >   it "should do stuff" do
> > >     @thing.should do_stuff
> > >   end
> > > end
> > >
> > > describe SpecificThing do
> > >   it_should_behave_like "anything", :thing => SpecificThing.new
> > > end
> > >
> > > Now comes the tricky part. This can work one of two ways. In either
> > > case it turns :thing into an instance variable @thing. The question is
> > > whether that instance variable is assigned in the scope of the
> > > SpecificThing example group or in a scope created especially to run
> > > the shared examples. Each choice presents usability confusion in my
> > > view.
> > >
> > > Imagine this scenario:
> > >
> > > shared_examples_for "anything" do
> > >   it "should do stuff" do
> > >     @thing.should do_stuff
> > >   end
> > >   it "should be like another thing" do
> > >     @thing.should be_like(@other_thing)
> > >   end
> > > end
> > >
> > > describe SpecificThing do
> > >   before(:each) do
> > >     @thing = SpecificThing.new
> > >   end
> > >   it_should_behave_like "anything", :other_thing => SpecificThing.new
> > >
> > >   it "should not be unlike other thing" do
> > >     @thing.should_not be_unlike(@other_thing)
> > >   end
> > > end
> > >
> > > If @other_thing is defined in the context of a separate scope just to
> > > run the shared examples, the shared examples won't know about @thing.
> > >
> > > If @other_thing in the scope of the example group created by "describe
> > > SpecificThing," then it's just confusing to look at - both
> > > before(:each) and it_should_behave_like are creating instance
> > > variables in the current scope, and it is NOT clear that is what is
> > > happening.
> > >
> > > If we go w/ the separate scope, then the metaphor of
> > > it_should_behave_like is wrong, because we're not talking about
> > > something in the current scope that should behave like something else
> > > anymore. We'd probably want a different construct to create these,
> > > even though the underlying mechanism would be the same.
> > >
> > > Thoughts?
> >
> >
> > How about this:
> >
> > Use a separate scope, but copy the instance variables from the
> > calling example group.  Any parameters passed into the shared example
> > group will be methods which wrap the values given.   This way we
> > don't have instance variable naming conflicts (like @other_thing, in
> > the example above).
> >
> > On the other hand, this would also mean that shared example groups
> > wouldn't have the ability to call methods in the calling example group.
> >
> > Thoughts?
>
> Copying instance variables around is nasty business. In fact, we
> eliminated that from shared behaviours by making them modules that get
> included! So I would view that as a step backwards from an
> implementation standpoint, and it still feels like voodoo from a
> usability standpoint.

Well - THAT was nothing but negative.

Let me add some positive to balance things:

As I think about it, I'm more inclined to make this a completely
different method, as I suggested as an option earlier. Something that
says "run in another scope with these variables." That way there's no
magic and consequently no confusion.

Suggestions?


More information about the rspec-users mailing list