[rspec-users] a better "should have valid associations"

Brandon Keepers bkeepers at gmail.com
Fri Mar 30 14:09:18 EDT 2007


I need to keep up with this list more.  I hadn't read the posts from  
yesterday and implemented a matcher this morning based off of Craig's  
post to the Grand Rapids Ruby group list[1].

module Spec
   module Rails
     module Matchers
       class HaveAssociation  #:nodoc:

         def initialize(type, name, options = {})
           @type = type
           @name = name
           @options = options
           @class_name = options[:class_name] ||  
@name.to_s.singularize.camelize
         end

         def matches?(model)
           @model = model
           @association = model.reflect_on_association(@name)

           @association && @association.macro == @type &&
             @association.class_name == @class_name &&
             @association.options == @options
         end

         def failure_message
           "expected #{model.inspect} to have a #{type} association  
called '#{name}', but got #{association.inspect}"
         end

         def description
           "have a #{type} association called :#{name}"
         end

         private
           attr_reader :type, :name, :model, :association
       end

       def have_association(type, name, options = {})
         HaveAssociation.new(type, name, options)
       end
     end
   end
end


and in my spec:

context "A comment" do
   specify "should belong to a message" do
     Comment.should have_association 
(:belongs_to, :message, :class_name => 'Post', :foreign_key =>  
'custom_foreign_key')
   end
end

The only thing I don't like about this approach (and ones similar) is  
that it only checks the declaration.  While that is important, I also  
think specs need to check that the declaration actually works  
(foreign key exists in database, model exists, etc.).

Brandon

[1] http://lists.gr-ruby.org/pipermail/discuss-gr-ruby.org/2007-March/ 
000568.html


On Mar 29, 2007, at 11:35 AM, Josh Knowles wrote:

>
>
> On 3/29/07, David Chelimsky <dchelimsky at gmail.com> wrote:
>
> How about this?
>
> project.should belong_to(:manager)
> manager.should have_many(:projects)
>
> etc
>
> This would involve more matchers, but could be implemented in the same
> fashion as have_association is above.
>
>
> I've implenented the first pass at the following rails matchers:
>
> should belong_to(association)
> should have_many(association)
> should validate_confirmation_of(attribute)
> should validate_format_of(attribute, valid => [], invalid => [])
> should validate_lendth_of(attribute, range)
> should validate_presence_of(attribute)
> should validate_uniqueness_of(attribute)
>
> Plugin available here: http://svn.integrumtech.com/public/plugins/ 
> rspec_on_rails_matchers/
>
> I haven't had a chance to get the README done, or any rdoc, but  
> there are specs for the majority of the matchers.
>
> Comments / Suggestions Welcome!
>
> Josh
>
>
>
>
> -- 
> Josh Knowles
> joshknowles at gmail.com
> http://joshknowles.com
> _______________________________________________
> rspec-users mailing list
> rspec-users at rubyforge.org
> http://rubyforge.org/mailman/listinfo/rspec-users



More information about the rspec-users mailing list