I''ve found these two snippets of code useful and would love some feedback. first, .should_have_valid_associations usage: context "A new Product" do specify "should have valid associations" do @product.should_have_valid_associations end end code: (thanks to Wilson/Defiler for converting to rspec) module Spec module Expectations module Should class Base def have_valid_associations @target.save_without_validation @target.class.reflect_on_all_associations.each do |assoc| lambda { @target.send(assoc.name, true) }.should_not_raise end self end end end end end second, I had a problem where I''d renamed some fields in the model and didn''t want to manually spec out each method, but also didn''t want to go the ''null object'' route. assigns[:cart] = @cart = mock("cart") @cart.stub!(:attr_name).and_return(''cart'') @cart.stub!(:to_param).and_return(''99'') @cart.stub!(:class).and_return(Cart) Cart.content_columns.each { |c| @cart.stub!(c.name.to_sym) } Cart.reflect_on_all_associations.each do |assoc| @cart.stub!(assoc.name.to_sym).and_return([]) end @cart.stub!(:name).and_return(''cart'') As you can see it rapidly spirals out of control, but this snippet sets up all the associations and field names as stubs. Comments?
David Chelimsky
2007-Feb-17 00:08 UTC
[rspec-users] some fun functionality for all your specs
On 2/16/07, Courtenay <court3nay at gmail.com> wrote:> I''ve found these two snippets of code useful and would love some feedback. > > first, .should_have_valid_associations > usage: > > context "A new Product" do > specify "should have valid associations" do > @product.should_have_valid_associations > end > end > > code: (thanks to Wilson/Defiler for converting to rspec) > > module Spec > module Expectations > module Should > class Base > def have_valid_associations > @target.save_without_validation > @target.class.reflect_on_all_associations.each do |assoc| > lambda { @target.send(assoc.name, true) }.should_not_raise > end > self > end > end > end > end > endA couple of things. First, VERY COOL. Second, here''s how you can do it in 0.8 and later (coming soon): module ActiveRecordExpectations def have_valid_associations return Class.new do def matches?(model) @model = model @model.save_without_validation @invalid_associations = [] @target.class.reflect_on_all_associations.each do |assoc| begin @target.send(assoc.name, true) rescue @invalid_associations << assoc end end @invalid_associations.empty? end def failure_message "expected all valid associations, but the following were not valid: #{@invalid_associations.inspect}" end end end.new end context "A new Product" do include ActiveRecordExpectations specify "should have valid associations" do @product.should have_valid_associations end end The nice thing here is that you can give it better failure messages. Also, the expectation is not monkey patched onto Object. WDYT?> > > second, I had a problem where I''d renamed some fields in the model and > didn''t want to manually spec out each method, but also didn''t want to > go the ''null object'' route. assigns[:cart] = @cart = mock("cart") > > @cart.stub!(:attr_name).and_return(''cart'') > @cart.stub!(:to_param).and_return(''99'') > @cart.stub!(:class).and_return(Cart) > > Cart.content_columns.each { |c| > @cart.stub!(c.name.to_sym) > } > Cart.reflect_on_all_associations.each do |assoc| > @cart.stub!(assoc.name.to_sym).and_return([]) > end > @cart.stub!(:name).and_return(''cart'') > > As you can see it rapidly spirals out of control, but this snippet > sets up all the associations and field names as stubs. >Cool. We just added a mock_model method that does some similar stuff but on an instance of Mock (not an instance of a Model). This would be a good addition, wrapped in a method named stub_model: stub_model(Person) Would you consider submitting a patch w/ this method added to Spec::Rails::Runner::EvalContext? David> Comments? > _______________________________________________ > rspec-users mailing list > rspec-users at rubyforge.org > http://rubyforge.org/mailman/listinfo/rspec-users >
Graeme Nelson
2007-Feb-17 22:27 UTC
[rspec-users] some fun functionality for all your specs
Hi. I am not sure what the have_valid_associations is really testing. If I have a model, like so: class Address < ActiveRecord::Base belongs_to :order end and my spec looks like: context "A new address" do setup do @address = Address.new end specify "should have valid associations" do @address.should_have_valid_associations end end I have this false of security that should_have_valid_associations is testing my associations. However, if I or some other developer comes along and removes the :order association by accident, the spec will still pass. I think the following reads a little better, plus it will fail if someone comes along and accidently removes the order association: context "A new address" do setup do @address = Address.new end specify "should have order association" do Address.reflect_on_association(:order).should_not_be_nil end end Just my 2 cents. Thanks, Graeme Nelson On Feb 16, 2007, at 4:08 PM, David Chelimsky wrote:> On 2/16/07, Courtenay <court3nay at gmail.com> wrote: >> I''ve found these two snippets of code useful and would love some >> feedback. >> >> first, .should_have_valid_associations >> usage: >> >> context "A new Product" do >> specify "should have valid associations" do >> @product.should_have_valid_associations >> end >> end >> >> code: (thanks to Wilson/Defiler for converting to rspec) >> >> module Spec >> module Expectations >> module Should >> class Base >> def have_valid_associations >> @target.save_without_validation >> @target.class.reflect_on_all_associations.each do |assoc| >> lambda { @target.send(assoc.name, >> true) }.should_not_raise >> end >> self >> end >> end >> end >> end >> end > > A couple of things. First, VERY COOL. Second, here''s how you can do it > in 0.8 and later (coming soon): > > module ActiveRecordExpectations > def have_valid_associations > return Class.new do > def matches?(model) > @model = model > @model.save_without_validation > @invalid_associations = [] > @target.class.reflect_on_all_associations.each do |assoc| > begin > @target.send(assoc.name, true) > rescue > @invalid_associations << assoc > end > end > @invalid_associations.empty? > end > > def failure_message > "expected all valid associations, but the following were not > valid: #{@invalid_associations.inspect}" > end > end > end.new > end > > context "A new Product" do > include ActiveRecordExpectations > specify "should have valid associations" do > @product.should have_valid_associations > end > end > > The nice thing here is that you can give it better failure messages. > Also, the expectation is not monkey patched onto Object. > > WDYT? > >> >> >> second, I had a problem where I''d renamed some fields in the model >> and >> didn''t want to manually spec out each method, but also didn''t want to >> go the ''null object'' route. assigns[:cart] = @cart = mock("cart") >> >> @cart.stub!(:attr_name).and_return(''cart'') >> @cart.stub!(:to_param).and_return(''99'') >> @cart.stub!(:class).and_return(Cart) >> >> Cart.content_columns.each { |c| >> @cart.stub!(c.name.to_sym) >> } >> Cart.reflect_on_all_associations.each do |assoc| >> @cart.stub!(assoc.name.to_sym).and_return([]) >> end >> @cart.stub!(:name).and_return(''cart'') >> >> As you can see it rapidly spirals out of control, but this snippet >> sets up all the associations and field names as stubs. >> > > Cool. We just added a mock_model method that does some similar stuff > but on an instance of Mock (not an instance of a Model). This would be > a good addition, wrapped in a method named stub_model: > > stub_model(Person) > > Would you consider submitting a patch w/ this method added to > Spec::Rails::Runner::EvalContext? > > David > >> Comments? >> _______________________________________________ >> 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
On 2/17/07, Graeme Nelson <graeme.nelson at gmail.com> wrote:> Hi. > > I am not sure what the have_valid_associations is really testing. If > I have a model, like so: > > class Address < ActiveRecord::Base > belongs_to :order > end >try this class Address < ActiveRecord::Base belongs_to :fooxl end make sure there''s no Fooxl model. the ''valid associations'' there means that your association actually would work, were you to call it. It''s surprising how many associations don''t get tested at the model level.
On 2/17/07, Courtenay <court3nay at gmail.com> wrote:> On 2/17/07, Graeme Nelson <graeme.nelson at gmail.com> wrote: > > Hi. > > > > I am not sure what the have_valid_associations is really testing. If > > I have a model, like so: > > > > class Address < ActiveRecord::Base > > belongs_to :order > > end > > > > try this > > class Address < ActiveRecord::Base > belongs_to :fooxl > end > > make sure there''s no Fooxl model. > > the ''valid associations'' there means that your association actually > would work, were you to call it. It''s surprising how many > associations don''t get tested at the model level. >you could also try belongs_to :order, :foreign_key => ''monkey_id'' and it''ll fail the spec.
Graeme Nelson
2007-Feb-18 15:27 UTC
[rspec-users] some fun functionality for all your specs
Thanks for the clarification, Courtenay. I didn''t realize that you were testing to see if :order actually exists. I would still want to know if someone removed the ''belongs_to :orders'', so I might still include Address.reflect_on_association :orders. Thanks Graeme Nelson On Feb 17, 2007, at 9:52 PM, Courtenay wrote:> On 2/17/07, Courtenay <court3nay at gmail.com> wrote: >> On 2/17/07, Graeme Nelson <graeme.nelson at gmail.com> wrote: >>> Hi. >>> >>> I am not sure what the have_valid_associations is really >>> testing. If >>> I have a model, like so: >>> >>> class Address < ActiveRecord::Base >>> belongs_to :order >>> end >>> >> >> try this >> >> class Address < ActiveRecord::Base >> belongs_to :fooxl >> end >> >> make sure there''s no Fooxl model. >> >> the ''valid associations'' there means that your association actually >> would work, were you to call it. It''s surprising how many >> associations don''t get tested at the model level. >> > > you could also try > > belongs_to :order, :foreign_key => ''monkey_id'' > > and it''ll fail the spec. > _______________________________________________ > rspec-users mailing list > rspec-users at rubyforge.org > http://rubyforge.org/mailman/listinfo/rspec-users
Ashley Moran
2007-Feb-19 13:57 UTC
[rspec-users] some fun functionality for all your specs
On 18 Feb 2007, at 05:41, Courtenay wrote:> the ''valid associations'' there means that your association actually > would work, were you to call it. It''s surprising how many > associations don''t get tested at the model level.We''ve been pretty good at this on our current project. I think our test:code ratio would pretty much half if we could test associations in one line :(