[rspec-users] Mock or Stub strategy for validates_uniqueness_of

Mikel Lindsaar raasdnil at gmail.com
Tue Jul 24 19:16:33 EDT 2007


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
>


More information about the rspec-users mailing list