Daniel N
2007-Jul-24 13:07 UTC
[rspec-users] Mock or Stub strategy for validates_uniqueness_of
Hi, I''m a bit stuck with mocking a unit test of a join model with regards to a validates_uniqueness_of clause. I have class Book < AR:B has_many :clippings various validates_presence_of etc end class Clip < AR:B has_many :clippings various validates_presence_of etc end class Clipping < AR:B belongs_to :book belongs_to :clip validates_uniqueness_of :clip_id, :scope => :book_id end What I want to do is just confirm that the validates uniqueness_of clause is set and functioning correctly in the spec for the clipping model. So if I was using fixtures I would do something like it "should not allow duplicate clips in the same book" do clip = clips( :some_clip ) book = books( :some_book ) lambda do clipping = Clipping.create( :clip => clip, :book => book ) end.should change( Clipping, :count ).by( 1 ) lambda do clipping = Clipping.create( :clip => clip, :book => ) clipping.should_not be_valid end.should_not change( Clipping, :count ) end Any hints as to how to do this without using fixtures? Cheers Daniel -------------- next part -------------- An HTML attachment was scrubbed... URL: http://rubyforge.org/pipermail/rspec-users/attachments/20070724/d3118a91/attachment-0001.html
Ashley Moran
2007-Jul-24 13:42 UTC
[rspec-users] Mock or Stub strategy for validates_uniqueness_of
On 24 Jul 2007, at 14:07, Daniel N wrote:> Any hints as to how to do this without using fixtures?I did this literally minutes ago. I don''t use fixtures at all, ever. Instead I put the data in the before block, eg: describe Purchase, "assigned to a Quote that already has a saved purchase" do before(:each) do @dealer = Dealer.create!(:name => "Dealer1", :external_identifier => "D123") @site = Site.create!(:hostname => "my.host.name", :dealer => @dealer) @provider = Provider.create!(:name => "Provider1") @product = Product.create!(:name => "Product1", :provider => @provider) @applicant = Applicant.create!(:first_name => "Fred", :last_name => "Flinstone", :email => "fred at flinstone.com", :telephone_home => "01782 123456") @quote_parameters = QuoteParameters.create!(:term => 36, :applicant => @applicant, :product => @product, :site => @site) @quote = InsuranceQuote.create!(:valid_until => 1.days.from_now, :quote_parameters => @quote_parameters, :premium => 250) Purchase.create!(:quote => @quote, :amount_financed => 200) end it "should be invalid" do purchase = Purchase.new(:quote => @quote, :amount_collected_by_card => "value") purchase.should_not be_valid purchase.errors.on(:quote_id).should_not be_nil end end Comments welcome on whether this is a good way to do this. (I know that the above doesn''t test my database unique constraint, which I don''t do in this case come to think of it, but I try to keep DB specs separate, hard as that may be sometimes.) Ashley
Daniel N
2007-Jul-24 13:49 UTC
[rspec-users] Mock or Stub strategy for validates_uniqueness_of
On 7/24/07, Ashley Moran <work at ashleymoran.me.uk> wrote:> > > On 24 Jul 2007, at 14:07, Daniel N wrote: > > > Any hints as to how to do this without using fixtures? > > I did this literally minutes ago. I don''t use fixtures at all, > ever. Instead I put the data in the before block, eg: > > describe Purchase, "assigned to a Quote that already has a saved > purchase" do > before(:each) do > @dealer = Dealer.create!(:name => > "Dealer1", :external_identifier => "D123") > @site = Site.create!(:hostname => "my.host.name", :dealer => > @dealer) > > @provider = Provider.create!(:name => "Provider1") > @product = Product.create!(:name => "Product1", :provider => > @provider) > @applicant = Applicant.create!(:first_name => "Fred", :last_name > => "Flinstone", :email => "fred at flinstone.com", :telephone_home => > "01782 123456") > @quote_parameters = QuoteParameters.create!(:term => > 36, :applicant => @applicant, :product => @product, :site => @site) > @quote = InsuranceQuote.create!(:valid_until => > 1.days.from_now, :quote_parameters => @quote_parameters, :premium => > 250) > Purchase.create!(:quote => @quote, :amount_financed => 200) > end > > it "should be invalid" do > purchase = Purchase.new(:quote => > @quote, :amount_collected_by_card => "value") > purchase.should_not be_valid > purchase.errors.on(:quote_id).should_not be_nil > end > end > > Comments welcome on whether this is a good way to do this. (I know > that the above doesn''t test my database unique constraint, which I > don''t do in this case come to think of it, but I try to keep DB specs > separate, hard as that may be sometimes.) > > AshleyThat looks like the kind of thing I was initially thinking of, but I started to think that having all those objects being created in a non-related spec could lead to trouble. If I change what makes any of those objects valid, these supposedly unrelated specs will then break. I want to try and keep everything seperate, but in this case it seems that things are interdependent. Cheers Daniel -------------- next part -------------- An HTML attachment was scrubbed... URL: http://rubyforge.org/pipermail/rspec-users/attachments/20070724/53e8aedd/attachment.html
Daniel N
2007-Jul-24 14:40 UTC
[rspec-users] Mock or Stub strategy for validates_uniqueness_of
On 7/24/07, Daniel N <has.sox at gmail.com> wrote:> > > > On 7/24/07, Ashley Moran <work at ashleymoran.me.uk> wrote: > > > > > > On 24 Jul 2007, at 14:07, Daniel N wrote: > > > > > Any hints as to how to do this without using fixtures? > > > > I did this literally minutes ago. I don''t use fixtures at all, > > ever. Instead I put the data in the before block, eg: > > > > describe Purchase, "assigned to a Quote that already has a saved > > purchase" do > > before(:each) do > > @dealer = Dealer.create!(:name => > > "Dealer1", :external_identifier => "D123") > > @site = Site.create!(:hostname => "my.host.name", :dealer => > > @dealer) > > > > @provider = Provider.create!(:name => "Provider1") > > @product = Product.create!(:name => "Product1", :provider => > > @provider) > > @applicant = Applicant.create!(:first_name => "Fred", :last_name > > => "Flinstone", :email => " fred at flinstone.com", :telephone_home => > > "01782 123456") > > @quote_parameters = QuoteParameters.create!(:term => > > 36, :applicant => @applicant, :product => @product, :site => @site) > > @quote = InsuranceQuote.create!(:valid_until => > > 1.days.from_now, :quote_parameters => @quote_parameters, :premium => > > 250) > > Purchase.create!(:quote => @quote, :amount_financed => 200) > > end > > > > it "should be invalid" do > > purchase = Purchase.new(:quote => > > @quote, :amount_collected_by_card => "value") > > purchase.should_not be_valid > > purchase.errors.on (:quote_id).should_not be_nil > > end > > end > > > > Comments welcome on whether this is a good way to do this. (I know > > that the above doesn''t test my database unique constraint, which I > > don''t do in this case come to think of it, but I try to keep DB specs > > separate, hard as that may be sometimes.) > > > > Ashley > > > That looks like the kind of thing I was initially thinking of, but I > started to think that having all those objects being created in a > non-related spec could lead to trouble. If I change what makes any of those > objects valid, these supposedly unrelated specs will then break. > > I want to try and keep everything seperate, but in this case it seems that > things are interdependent. > > Cheers > Daniel >What I''ve ended up doing is the following test it "should have a uniq clip_id for a given book" do lambda do Clipping.create( valid_clipping_attributes ) Clipping.create( valid_clipping_attributes ) end.should change( Clipping, :count ).by( 1 ) end It hits the database, but the valid_clipping_attributes are mocks that are used throughout the spec so it''s divorced from the other specs. If there are any better ideas I''m open to them. Thanx for the response Ashley. Daniel -------------- next part -------------- An HTML attachment was scrubbed... URL: http://rubyforge.org/pipermail/rspec-users/attachments/20070725/d701aec4/attachment.html
Mikel Lindsaar
2007-Jul-24 23:16 UTC
[rspec-users] Mock or Stub strategy for validates_uniqueness_of
There would be a different way. In the idea of "Only test the code you write" all you really need to spec is that you have set the right association, because activerecord has it''s own tests to ensure the uniq call works. You can do this with a call to reflect_on_association. Unfortunately that call does not return a hash, but an association object. I wrote a blog post on how to do this easily with a spec_helper.rb method that adds to_hash to reflect on association. http://www.blognow.com.au/q/67540/Reflect_on_association_one_liner_to_check_association_details.html In the end you end up with a spec that looks like this: it "should test reflection details" do association_results = { :macro => :has_many, :options => {:through => :clipping, :uniq => true}, :class_name => "nil" } Book.reflect_on_association(:clip).to_hash.should == association_results end Of course, you can add whatever values you want into the hash. I now have one of these specs at the top of pretty much every model spec. Just set up the hash with all your association rules and then this can be checked and kept track of when you are refactoring or changing code. Hope that helps. Regards Mikel On 7/25/07, Daniel N <has.sox at gmail.com> wrote:> > > > On 7/24/07, Daniel N <has.sox at gmail.com> wrote: > > > > > > > > > > On 7/24/07, Ashley Moran < work at ashleymoran.me.uk> wrote: > > > > > > On 24 Jul 2007, at 14:07, Daniel N wrote: > > > > > > > Any hints as to how to do this without using fixtures? > > > > > > I did this literally minutes ago. I don''t use fixtures at all, > > > ever. Instead I put the data in the before block, eg: > > > > > > describe Purchase, "assigned to a Quote that already has a saved > > > purchase" do > > > before(:each) do > > > @dealer = Dealer.create!(:name => > > > "Dealer1", :external_identifier => "D123") > > > @site = Site.create!(:hostname => "my.host.name", :dealer => > > > @dealer) > > > > > > @provider = Provider.create!(:name => "Provider1") > > > @product = Product.create!(:name => "Product1", :provider => > > > @provider) > > > @applicant = Applicant.create!(:first_name => "Fred", :last_name > > > => "Flinstone", :email => " fred at flinstone.com", :telephone_home => > > > "01782 123456") > > > @quote_parameters = QuoteParameters.create!(:term => > > > 36, :applicant => @applicant, :product => @product, :site => @site) > > > @quote = InsuranceQuote.create!(:valid_until => > > > 1.days.from_now, :quote_parameters => @quote_parameters, :premium => > > > 250) > > > Purchase.create!(:quote => @quote, :amount_financed => 200) > > > end > > > > > > it "should be invalid" do > > > purchase = Purchase.new(:quote => > > > @quote, :amount_collected_by_card => "value") > > > purchase.should_not be_valid > > > purchase.errors.on (:quote_id).should_not be_nil > > > end > > > end > > > > > > Comments welcome on whether this is a good way to do this. (I know > > > that the above doesn''t test my database unique constraint, which I > > > don''t do in this case come to think of it, but I try to keep DB specs > > > separate, hard as that may be sometimes.) > > > > > > Ashley > > > > > > That looks like the kind of thing I was initially thinking of, but I > started to think that having all those objects being created in a > non-related spec could lead to trouble. If I change what makes any of those > objects valid, these supposedly unrelated specs will then break. > > > > I want to try and keep everything seperate, but in this case it seems that > things are interdependent. > > > > Cheers > > Daniel > > What I''ve ended up doing is the following test > > it "should have a uniq clip_id for a given book" do > lambda do > Clipping.create( valid_clipping_attributes ) > Clipping.create( valid_clipping_attributes ) > end.should change( Clipping, :count ).by( 1 ) > end > > It hits the database, but the valid_clipping_attributes are mocks that are > used throughout the spec so it''s divorced from the other specs. > > If there are any better ideas I''m open to them. > > Thanx for the response Ashley. > > Daniel > > > > _______________________________________________ > rspec-users mailing list > rspec-users at rubyforge.org > http://rubyforge.org/mailman/listinfo/rspec-users >
Daniel N
2007-Jul-24 23:46 UTC
[rspec-users] Mock or Stub strategy for validates_uniqueness_of
On 7/25/07, Mikel Lindsaar <raasdnil at gmail.com> wrote:> > There would be a different way. > > In the idea of "Only test the code you write" all you really need to > spec is that you have set the right association, because activerecord > has it''s own tests to ensure the uniq call works. > > You can do this with a call to reflect_on_association. Unfortunately > that call does not return a hash, but an association object. > > I wrote a blog post on how to do this easily with a spec_helper.rb > method that adds to_hash to reflect on association. > > > http://www.blognow.com.au/q/67540/Reflect_on_association_one_liner_to_check_association_details.html > > In the end you end up with a spec that looks like this: > > it "should test reflection details" do > > association_results = { > :macro => :has_many, > :options => {:through => :clipping, :uniq => true}, > :class_name => "nil" > } > > Book.reflect_on_association(:clip).to_hash.should => association_results > > end > > > Of course, you can add whatever values you want into the hash. > > I now have one of these specs at the top of pretty much every model > spec. Just set up the hash with all your association rules and then > this can be checked and kept track of when you are refactoring or > changing code. > > Hope that helps. > > Regards > > MikelThanx Mikel. I didn''t even think of using a uniq on the has_many. I was using a validates_uniquness_of :scope => ''book_id'' I will definitley look into this one. Thankyou Daniel On 7/25/07, Daniel N <has.sox at gmail.com> wrote:> > > > > > > > On 7/24/07, Daniel N <has.sox at gmail.com> wrote: > > > > > > > > > > > > > > > On 7/24/07, Ashley Moran < work at ashleymoran.me.uk> wrote: > > > > > > > > On 24 Jul 2007, at 14:07, Daniel N wrote: > > > > > > > > > Any hints as to how to do this without using fixtures? > > > > > > > > I did this literally minutes ago. I don''t use fixtures at all, > > > > ever. Instead I put the data in the before block, eg: > > > > > > > > describe Purchase, "assigned to a Quote that already has a saved > > > > purchase" do > > > > before(:each) do > > > > @dealer = Dealer.create!(:name => > > > > "Dealer1", :external_identifier => "D123") > > > > @site = Site.create!(:hostname => "my.host.name", :dealer => > > > > @dealer) > > > > > > > > @provider = Provider.create!(:name => "Provider1") > > > > @product = Product.create!(:name => "Product1", :provider => > > > > @provider) > > > > @applicant = Applicant.create!(:first_name => "Fred", > :last_name > > > > => "Flinstone", :email => " fred at flinstone.com", :telephone_home => > > > > "01782 123456") > > > > @quote_parameters = QuoteParameters.create!(:term => > > > > 36, :applicant => @applicant, :product => @product, :site => @site) > > > > @quote = InsuranceQuote.create!(:valid_until => > > > > 1.days.from_now, :quote_parameters => @quote_parameters, :premium => > > > > 250) > > > > Purchase.create!(:quote => @quote, :amount_financed => 200) > > > > end > > > > > > > > it "should be invalid" do > > > > purchase = Purchase.new(:quote => > > > > @quote, :amount_collected_by_card => "value") > > > > purchase.should_not be_valid > > > > purchase.errors.on (:quote_id).should_not be_nil > > > > end > > > > end > > > > > > > > Comments welcome on whether this is a good way to do this. (I know > > > > that the above doesn''t test my database unique constraint, which I > > > > don''t do in this case come to think of it, but I try to keep DB > specs > > > > separate, hard as that may be sometimes.) > > > > > > > > Ashley > > > > > > > > > That looks like the kind of thing I was initially thinking of, but I > > started to think that having all those objects being created in a > > non-related spec could lead to trouble. If I change what makes any of > those > > objects valid, these supposedly unrelated specs will then break. > > > > > > I want to try and keep everything seperate, but in this case it seems > that > > things are interdependent. > > > > > > Cheers > > > Daniel > > > > What I''ve ended up doing is the following test > > > > it "should have a uniq clip_id for a given book" do > > lambda do > > Clipping.create( valid_clipping_attributes ) > > Clipping.create( valid_clipping_attributes ) > > end.should change( Clipping, :count ).by( 1 ) > > end > > > > It hits the database, but the valid_clipping_attributes are mocks that > are > > used throughout the spec so it''s divorced from the other specs. > > > > If there are any better ideas I''m open to them. > > > > Thanx for the response Ashley. > > > > Daniel > > > > > > > > _______________________________________________ > > rspec-users mailing list > > rspec-users at rubyforge.org > > http://rubyforge.org/mailman/listinfo/rspec-users > > > _______________________________________________ > rspec-users mailing list > rspec-users at rubyforge.org > http://rubyforge.org/mailman/listinfo/rspec-users >-------------- next part -------------- An HTML attachment was scrubbed... URL: http://rubyforge.org/pipermail/rspec-users/attachments/20070725/c0afd796/attachment.html
Kyle Hargraves
2007-Jul-25 00:07 UTC
[rspec-users] Mock or Stub strategy for validates_uniqueness_of
Daniel N wrote:> On 7/25/07, Mikel Lindsaar <raasdnil at gmail.com> wrote: >> >> There would be a different way. >> >> In the idea of "Only test the code you write" all you really need to >> spec is that you have set the right association, because activerecord >> has it''s own tests to ensure the uniq call works. >> >> You can do this with a call to reflect_on_association. Unfortunately >> that call does not return a hash, but an association object. >> >> I wrote a blog post on how to do this easily with a spec_helper.rb >> method that adds to_hash to reflect on association. >> >> >> http://www.blognow.com.au/q/67540/Reflect_on_association_one_liner_to_check_association_details.html >> >> >> In the end you end up with a spec that looks like this: >> >> it "should test reflection details" do >> >> association_results = { >> :macro => :has_many, >> :options => {:through => :clipping, :uniq => true}, >> :class_name => "nil" >> } >> >> Book.reflect_on_association(:clip).to_hash.should =>> association_results >> >> end >> >> >> Of course, you can add whatever values you want into the hash. >> >> I now have one of these specs at the top of pretty much every model >> spec. Just set up the hash with all your association rules and then >> this can be checked and kept track of when you are refactoring or >> changing code. >> >> Hope that helps. >> >> Regards >> >> Mikel > > > Thanx Mikel. > > I didn''t even think of using a uniq on the has_many. I was using a > validates_uniquness_of :scope => ''book_id'' > > I will definitley look into this one. > > Thankyou > DanielHowever you decide to go about solving it, the idiom you hit upon is what, to me, actually describes the behaviour; if the book already has a clip once, you can''t add it again: lambda { add_twice }.should change(...).by(1) It states very clearly what results you wish to see. Going through reflect_on_association feels too much like specifying the use of a particular implementation, rather than the desired outcome. Kyle
Daniel N
2007-Jul-25 00:31 UTC
[rspec-users] Mock or Stub strategy for validates_uniqueness_of
On 7/25/07, Kyle Hargraves <philodespotos at gmail.com> wrote:> > Daniel N wrote: > > On 7/25/07, Mikel Lindsaar <raasdnil at gmail.com> wrote: > >> > >> There would be a different way. > >> > >> In the idea of "Only test the code you write" all you really need to > >> spec is that you have set the right association, because activerecord > >> has it''s own tests to ensure the uniq call works. > >> > >> You can do this with a call to reflect_on_association. Unfortunately > >> that call does not return a hash, but an association object. > >> > >> I wrote a blog post on how to do this easily with a spec_helper.rb > >> method that adds to_hash to reflect on association. > >> > >> > >> > http://www.blognow.com.au/q/67540/Reflect_on_association_one_liner_to_check_association_details.html > >> > >> > >> In the end you end up with a spec that looks like this: > >> > >> it "should test reflection details" do > >> > >> association_results = { > >> :macro => :has_many, > >> :options => {:through => :clipping, :uniq => true}, > >> :class_name => "nil" > >> } > >> > >> Book.reflect_on_association(:clip).to_hash.should => >> association_results > >> > >> end > >> > >> > >> Of course, you can add whatever values you want into the hash. > >> > >> I now have one of these specs at the top of pretty much every model > >> spec. Just set up the hash with all your association rules and then > >> this can be checked and kept track of when you are refactoring or > >> changing code. > >> > >> Hope that helps. > >> > >> Regards > >> > >> Mikel > > > > > > Thanx Mikel. > > > > I didn''t even think of using a uniq on the has_many. I was using a > > validates_uniquness_of :scope => ''book_id'' > > > > I will definitley look into this one. > > > > Thankyou > > Daniel > > However you decide to go about solving it, the idiom you hit upon is > what, to me, actually describes the behaviour; if the book already has a > clip once, you can''t add it again: > > lambda { add_twice }.should change(...).by(1) > > It states very clearly what results you wish to see. > > Going through reflect_on_association feels too much like specifying the > use of a particular implementation, rather than the desired outcome. > > KyleIt looks much better when you write it like that though ;) -------------- next part -------------- An HTML attachment was scrubbed... URL: http://rubyforge.org/pipermail/rspec-users/attachments/20070725/51ecc28f/attachment.html
Mikel Lindsaar
2007-Jul-25 03:58 UTC
[rspec-users] Mock or Stub strategy for validates_uniqueness_of
Kyle, That is a good point. We are after the behaviour, not the implementation. Regards Mikel On 7/25/07, Daniel N <has.sox at gmail.com> wrote:> > > > On 7/25/07, Kyle Hargraves <philodespotos at gmail.com> wrote: > > Daniel N wrote: > > > On 7/25/07, Mikel Lindsaar <raasdnil at gmail.com> wrote: > > >> > > >> There would be a different way. > > >> > > >> In the idea of "Only test the code you write" all you really need to > > >> spec is that you have set the right association, because activerecord > > >> has it''s own tests to ensure the uniq call works. > > >> > > >> You can do this with a call to > reflect_on_association. Unfortunately > > >> that call does not return a hash, but an association object. > > >> > > >> I wrote a blog post on how to do this easily with a spec_helper.rb > > >> method that adds to_hash to reflect on association. > > >> > > >> > > >> > http://www.blognow.com.au/q/67540/Reflect_on_association_one_liner_to_check_association_details.html > > >> > > >> > > >> In the end you end up with a spec that looks like this: > > >> > > >> it "should test reflection details" do > > >> > > >> association_results = { > > >> :macro => :has_many, > > >> :options => {:through => :clipping, :uniq => true}, > > >> :class_name => "nil" > > >> } > > >> > > >> Book.reflect_on_association (:clip).to_hash.should => > >> association_results > > >> > > >> end > > >> > > >> > > >> Of course, you can add whatever values you want into the hash. > > >> > > >> I now have one of these specs at the top of pretty much every model > > >> spec. Just set up the hash with all your association rules and then > > >> this can be checked and kept track of when you are refactoring or > > >> changing code. > > >> > > >> Hope that helps. > > >> > > >> Regards > > >> > > >> Mikel > > > > > > > > > Thanx Mikel. > > > > > > I didn''t even think of using a uniq on the has_many. I was using a > > > validates_uniquness_of :scope => ''book_id'' > > > > > > I will definitley look into this one. > > > > > > Thankyou > > > Daniel > > > > However you decide to go about solving it, the idiom you hit upon is > > what, to me, actually describes the behaviour; if the book already has a > > clip once, you can''t add it again: > > > > lambda { add_twice }.should change(...).by(1) > > > > It states very clearly what results you wish to see. > > > > Going through reflect_on_association feels too much like specifying the > > use of a particular implementation, rather than the desired outcome. > > > > Kyle > > > It looks much better when you write it like that though ;) > > > > _______________________________________________ > rspec-users mailing list > rspec-users at rubyforge.org > http://rubyforge.org/mailman/listinfo/rspec-users >
Daniel N
2007-Jul-25 10:31 UTC
[rspec-users] Mock or Stub strategy for validates_uniqueness_of
On 7/25/07, Mikel Lindsaar <raasdnil at gmail.com> wrote:> > Kyle, > > That is a good point. We are after the behaviour, not the implementation. > > Regards > > Mikel > > On 7/25/07, Daniel N <has.sox at gmail.com> wrote: > > > > > > > > On 7/25/07, Kyle Hargraves <philodespotos at gmail.com> wrote: > > > Daniel N wrote: > > > > On 7/25/07, Mikel Lindsaar <raasdnil at gmail.com> wrote: > > > >> > > > >> There would be a different way. > > > >> > > > >> In the idea of "Only test the code you write" all you really need > to > > > >> spec is that you have set the right association, because > activerecord > > > >> has it''s own tests to ensure the uniq call works. > > > >> > > > >> You can do this with a call to > > reflect_on_association. Unfortunately > > > >> that call does not return a hash, but an association object. > > > >> > > > >> I wrote a blog post on how to do this easily with a spec_helper.rb > > > >> method that adds to_hash to reflect on association. > > > >> > > > >> > > > >> > > > http://www.blognow.com.au/q/67540/Reflect_on_association_one_liner_to_check_association_details.html > > > >> > > > >> > > > >> In the end you end up with a spec that looks like this: > > > >> > > > >> it "should test reflection details" do > > > >> > > > >> association_results = { > > > >> :macro => :has_many, > > > >> :options => {:through => :clipping, :uniq => true}, > > > >> :class_name => "nil" > > > >> } > > > >> > > > >> Book.reflect_on_association (:clip).to_hash.should => > > >> association_results > > > >> > > > >> end > > > >> > > > >> > > > >> Of course, you can add whatever values you want into the hash. > > > >> > > > >> I now have one of these specs at the top of pretty much every model > > > >> spec. Just set up the hash with all your association rules and > then > > > >> this can be checked and kept track of when you are refactoring or > > > >> changing code. > > > >> > > > >> Hope that helps. > > > >> > > > >> Regards > > > >> > > > >> Mikel > > > > > > > > > > > > Thanx Mikel. > > > > > > > > I didn''t even think of using a uniq on the has_many. I was using a > > > > validates_uniquness_of :scope => ''book_id'' > > > > > > > > I will definitley look into this one. > > > > > > > > Thankyou > > > > Daniel > > > > > > However you decide to go about solving it, the idiom you hit upon is > > > what, to me, actually describes the behaviour; if the book already has > a > > > clip once, you can''t add it again: > > > > > > lambda { add_twice }.should change(...).by(1) > > > > > > It states very clearly what results you wish to see. > > > > > > Going through reflect_on_association feels too much like specifying > the > > > use of a particular implementation, rather than the desired outcome. > > > > > > Kyle > > > > > > It looks much better when you write it like that though ;) > > > > > >Thanx for the input guys. I wasn''''t entirely happy with what I had because it didn''t actually test what I wanted. It tests that a duplicate cannot be added. But I specifically wanted to not allow duplicates for a given clip_id it "should have a uniq clip_id for a given book" do lambda do Clipping.create( valid_clipping_attributes ) Clipping.create( valid_clipping_attributes ) end.should change( Clipping, :count ).by( 1 ) end became it "should have a uniq clip_id for a given book" do lambda do Clipping.create( valid_clipping_attributes.with( :book => @book, :clip => @clip ) ) clipping = Clipping.create( valid_clipping_attributes.with( :book => @book, :clip => @clip ) ) clipping.should have(1).error_on( :clip_id ) clipping.errors.on( :clip_id ).should match( /(already|duplicate|exists)/i ) end.should change( Clipping, :count ).by( 1 ) end If anyone was interested :P Daniel -------------- next part -------------- An HTML attachment was scrubbed... URL: http://rubyforge.org/pipermail/rspec-users/attachments/20070725/db8d118b/attachment.html
Ashley Moran
2007-Jul-25 14:24 UTC
[rspec-users] Mock or Stub strategy for validates_uniqueness_of
On 24 Jul 2007, at 14:49, Daniel N wrote:> That looks like the kind of thing I was initially thinking of, but > I started to think that having all those objects being created in a > non-related spec could lead to trouble. If I change what makes any > of those objects valid, these supposedly unrelated specs will then > break.Yep, I''ve had that several times unfortunately...> I want to try and keep everything seperate, but in this case it > seems that things are interdependent.from the other email...> It hits the database, but the valid_clipping_attributes are mocks > that are used throughout the spec so it''s divorced from the other > specs.I like the idea of separating out the valid atributes. Most of my models start along the lines of "An XModel created with valid attributes should be valid" this sanity checks that I know what a valid model is and means if anything goes wrong I don''t waste hours hunting through Ashley
Ashley Moran
2007-Jul-25 14:30 UTC
[rspec-users] Mock or Stub strategy for validates_uniqueness_of
On 25 Jul 2007, at 01:07, Kyle Hargraves wrote:> Going through reflect_on_association feels too much like specifying > the > use of a particular implementation, rather than the desired outcome.I second that. I agree that you should only test the code you write, but unfortunately(!) you get a lot of behaviour for each line of code you write in rails, so I prefer to test the expected behaviour than signs that the behaviour is in place Sometimes I''m forced to break this, in which case I write an assumption spec that tests a single case of what the library should be doing, then test that I interact with it properly. Ashley