[rspec-users] some fun functionality for all your specs

Graeme Nelson graeme.nelson at gmail.com
Sat Feb 17 17:27:04 EST 2007


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



More information about the rspec-users mailing list