[rspec-users] Formatting shared example descriptions with test data

Ashley Moran
Mon, 26 Jul 2010 16:15:47 -0000

On Jul 26, 2010, at 3:44 pm, Wincent Colaiuta wrote:

> Personally I wouldn''t do this. It makes it harder for anybody
coming to your project to understand what''s going on, because they see
this "contract ''foo'' do" construct and
don''t know what it is unless they dig into your spec_helper. If you
really want the word contract to appear in there I would just write the shared
examples like this:

Actually, this doesn''t bother me.  All the commercial development I do
is pair-programmed, so it doesn''t take long for anyone new to a project
to pick things like these up.  I prefer to improve the semantics at the expense
of some initial learning cost.  (As it happens, this isn''t a commercial
project anyway, it''s just something I''m doing on the side for
my own benefit.)


> So if I''m reading you correctly, this is where the "aspect of
behavior that can occur N times" comes in, right? AFAIK the typical way to
do this is via "macros" (ie. generating examples on the fly, typically
keeping to examples of one assertion per iteration of the loop). So
it''s just a minor tweak of what you''ve got there:
>
>  properties.each do |property|
>    it "is false if #{property} is different" do
>      ...
>    end
>  end

If you mean by using a custom matcher in there, then yeah, I get you.  But as
this is more extensive, shared examples (which prove many individual pieces of
behaviour) seemed a better fit than a matcher (which are intended to prove just
one).


> But alas, this pattern won''t work with shared example groups. I
don''t know of any way to pass the "properties" variable in
this case, and even if you could it wouldn''t work anyway because,
AFAIK, the shared example group is itself only evaluated once when the file is
first read. It isn''t re-evaluted each time it is included in another
example group. At least, that''s my understanding of it. I might be
wrong about that. So, looks like you''re stuck with having multiple
assertions inside a single "it" block.

Hmmm, if that''s the case, then this approach won''t work
anyway.  But I''ll investigate... it depends on the implementation.
This is one of the things I want to find out.


>> This is fine for a class, but the behaviour I want to prove with a
Collection needs to be mixed in once per collection, eg (the last two are made
up):
>>
>> describe User do
>>   it_satisfies_contract "Entity Collection", for:
"checklist_templates"
>>   it_satisfies_contract "Entity Collection", for:
"groups"
>>   it_satisfies_contract "Entity Collection", for:
"delegated_actions"
>> end
>
> Here the "standard" way of parametrizing this would be via blocks
("standard" in inverted commas because the ability to pass a block
here is such a recent addition to RSpec).

Yeah, I''m doing that to get the necessary objects inside the shared
example.  But as you pointed out, the scope inside example groups and inside the
examples themselves are very different.