It''s all gone a bit meta. I''ve started noticing patterns in my specs, where I want more than one class to satisfy a specific bunch of behaviours. I know I can use it_should_behave_like and this works in simple cases, but I want to be able to iterate around an array of values and generate a my bunch of it "should ..." specs for each item in the array. I know I can do this by going describe "the cheese factory" [:cheddar, :brie, :lancashire].each do |cheese| it "should create a valid piece of #{cheese}" do Factory.create(cheese).should be_valid end it "should create a piece of #{cheese} with valid packaging" do ... etc end end ...but what if I want to specify other factories too, all of which conform to the it blocks I specified above? (e.g. a ToyFactory that creates valid toys with valid packaging). How can I factor that spec logic out? I tried putting the content of the (do |cheese|) block into a method, but ruby doesn''t seem to be able to see that method when the describe block runs... I guess I need to maybe patch it into some RSpec class instead? Or put it into a module and include it? Am I going down the wrong lines? is there an easier way to achieve this? Sorry if this is a dumb question, I''m bumping up against the limitations of my ruby experience again :) cheers, Matt ---- http://blog.mattwynne.net http://songkick.com In case you wondered: The opinions expressed in this email are my own and do not necessarily reflect the views of any former, current or future employers of mine. -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://rubyforge.org/pipermail/rspec-users/attachments/20080915/342c0533/attachment.html>
Hi Matt, On Mon, Sep 15, 2008 at 12:28 PM, Matt Wynne <matt at mattwynne.net> wrote:> It''s all gone a bit meta. > I''ve started noticing patterns in my specs, where I want more than one class > to satisfy a specific bunch of behaviours. > I know I can use it_should_behave_like and this works in simple cases, but I > want to be able to iterate around an array of values and generate a my bunch > of it "should ..." specs for each item in the array. > I know I can do this by going > describe "the cheese factory" > [:cheddar, :brie, :lancashire].each do |cheese| > it "should create a valid piece of #{cheese}" do > Factory.create(cheese).should be_valid > end > it "should create a piece of #{cheese} with valid packaging" do > ... etc > end > end > ...but what if I want to specify other factories too, all of which conform > to the it blocksit blocks == code examples> I specified above? (e.g. a ToyFactory that creates valid > toys with valid packaging). How can I factor that spec logic out? > I tried putting the content of the (do |cheese|) block into a method, but > ruby doesn''t seem to be able to see that method when the describe block > runsHow are you doing that? Where are you putting the method? How are you calling it?> I guess I need to maybe patch it into some RSpec class instead? Or > put it into a module and include it? Am I going down the wrong lines? is > there an easier way to achieve this?Kind of depends on how you want the specs themselves to look. One approach is to wrap class level methods in a module and extend the example group with that module. This could, for example, give you example groups that look like this: describe CheeseFactory do extend FactoryExamples it_should_create :cheddar, :brie, :lancashire end describe GameFactory do extend FactoryExamples it_should_create :chess, :clue, :mastermind end Here''s some code (that doesn''t do much but actually works) to demonstrate: http://pastie.org/273290 HTH, David> cheers, > Matt > ---- > http://blog.mattwynne.net > http://songkick.com
On 16 Sep 2008, at 14:28, David Chelimsky wrote:> Hi Matt, > > On Mon, Sep 15, 2008 at 12:28 PM, Matt Wynne <matt at mattwynne.net> > wrote: >> It''s all gone a bit meta. >> I''ve started noticing patterns in my specs, where I want more than >> one class >> to satisfy a specific bunch of behaviours. >> I know I can use it_should_behave_like and this works in simple >> cases, but I >> want to be able to iterate around an array of values and generate >> a my bunch >> of it "should ..." specs for each item in the array. >> I know I can do this by going >> describe "the cheese factory" >> [:cheddar, :brie, :lancashire].each do |cheese| >> it "should create a valid piece of #{cheese}" do >> Factory.create(cheese).should be_valid >> end >> it "should create a piece of #{cheese} with valid packaging" do >> ... etc >> end >> end >> ...but what if I want to specify other factories too, all of which >> conform >> to the it blocks > > it blocks == code examples > >> I specified above? (e.g. a ToyFactory that creates valid >> toys with valid packaging). How can I factor that spec logic out? >> I tried putting the content of the (do |cheese|) block into a >> method, but >> ruby doesn''t seem to be able to see that method when the describe >> block >> runs > > How are you doing that? Where are you putting the method? How are you > calling it? > >> I guess I need to maybe patch it into some RSpec class instead? Or >> put it into a module and include it? Am I going down the wrong >> lines? is >> there an easier way to achieve this? > > Kind of depends on how you want the specs themselves to look. One > approach is to wrap class level methods in a module and extend the > example group with that module. This could, for example, give you > example groups that look like this: > > describe CheeseFactory do > extend FactoryExamples > it_should_create :cheddar, :brie, :lancashire > end > > describe GameFactory do > extend FactoryExamples > it_should_create :chess, :clue, :mastermind > end > > Here''s some code (that doesn''t do much but actually works) to > demonstrate: > > http://pastie.org/273290Bingo! My misunderstanding of include vs extend was to blame, I think. Thanks as usual. cheers, Matt ---- http://blog.mattwynne.net http://songkick.com In case you wondered: The opinions expressed in this email are my own and do not necessarily reflect the views of any former, current or future employers of mine.