2
votes

I'm using ruby 1.9.2 and rails 3.2.2.

I have a 'domain' model (domain.rb):

class Domain < ActiveRecord::Base
  attr_accessible :url
  belongs_to :user

  VALID_DOMAIN_REGEX = /^[a-z0-9\-\.]+\.[a-z]{2,}$/i
  validates :url, presence:true,
              format: { with: VALID_DOMAIN_REGEX },
              uniqueness: { case_sensitive: false }

end

And a test asserting that a duplicate domain should not be valid:

require 'spec_helper'

describe Domain do

  before do
    @domain = FactoryGirl.create(:domain)
  end

  subject { @domain }

  describe "when domain url is already taken" do
    before do
      domain_with_same_url = @domain.dup
      domain_with_same_url.url = @domain.url.upcase
      domain_with_same_url.save
    end
    it { should_not be_valid }
  end
end

The test keeps failing:

1) Domain when domain url is already taken Failure/Error: it { should_not be_valid } expected valid? to return false, got true # ./spec/models/domain_spec.rb:31:in `block (3 levels) in '

4

4 Answers

3
votes

@domain is already created, validated and saved.

The domain_with_same_url is the new record, and it should be invalid. But you are not checking it.

Try

domain_with_same_url = FactoryGirl.create(:domain, :url => @domain.url.upcase)
domain_with_same_url.should_not be_valid
0
votes

Your two before blocks are run in outer-to inner order. Thus, when running your testsuite, first your @domain object gets created and saved, then the inner before block gets executed. Hiwever, your domain_with_same_url probably gets never actually saved because it's validation fails which probably leats to domain_with_same_url.save to return false.

As a workaround, you could check the validity of domain_with_same_url instead of @domain.

0
votes

Seems like your subject of your test case is @domain, which is a valid object. Whether use new subject for @domain_with_same_url (don't forget to make it an instance variable), or explicitly say domain_with_same_url.should ... (just like The Who indicated in his answer).

0
votes

I just had the same problem in Rails 4 Model column uniqueness not working. It provides two other solutions without a second call to FactoryGirl, just FYI. The one I am using is:

before(:each) do
  @feed_with_same_url = @feed.dup
  @feed_with_same_url.feed_url = @feed.feed_url
end
it { @feed_with_same_url.should_not be_valid }

The save is causing some problem, unexpected to me. And, you need to reference an object to should_not_be_valid as a local variable.