0
votes

I'm using rspec, rails, guard and sorcery for my authentication and testing.

I have a test that is testing the length of an email. I want to reject emails that are too long. Here is the test I wrote for spec/models/user_spec.rb

    require 'spec_helper'

    describe User do
     before(:each) do
       @attr = { :email => "[email protected]", :password => "password", :password_confirmation => "password" }
     end


     it "should reject emails that are too long" do
       long_email = "a" * 101 + "gmail.com"
       long_email = User.new (@attr.merge(:email => long_email))
       long_email.should_not be_valid
     end

Here is the model validations I have in place:

class User < ActiveRecord::Base
  authenticates_with_sorcery!

  attr_accessible :email, :password, :password_confirmation

  validates_presence_of :password, :on => :create
  validates :password, :confirmation => true,
                       :length       => { :within => 6..100 }

  email_regex = /\A[\w+\-.]+@[a-z\d\-.]+\.[a-z]+\z/i
  validates :email, :presence        => true,
                    :format          => { :with => email_regex },
                    :uniqueness      => {:case_sensitive => false},
                    :length          => { :within => 5..100 }
end

I'm a noob with this stuff, so any help would be greatly appreciated. The test is green right now, it goes red if I change the line to long_email.should be_valid. Thanks in advance!

1
It sounds like your application is behaiving exactly as you intend it to. If you have your test as long_email.should_not be_valid, and your tests pass, that seems like what you want. If not, could you explain your problem in more detail?Chris Knadler
your email isn't too long, it's 60 characters and you accept < 100. Still the format is bad and the test should fail. Could you try to replace long_email.should_not be_valid with long_email.valid?.should be_falseapneadiving

1 Answers

1
votes

As @apneadiving points out, the format of test is important. It not only makes it easier to read, but also shows up places you haven't tested:

require 'spec_helper'

describe User do
  let(:attr){ 
    {:email => "[email protected]", :password => "password", :password_confirmation => "password" }
  }

  context "When given an email address" do
    context "That is too long" do
      let(:long_email){ "a" * 101 + "gmail.com" }
      subject{ User.new attr.merge(:email => long_email) }

      specify{ subject.should_not be_valid }
    end
    context "That is too short" do
      pending
    end
    context "That is between 5 and 100 characters long"
      pending
    end
  end

end

As you can see, rewriting it has done several things:

  • made it easier to read
  • made it easier to add more tests without having earlier tests impact later ones (by using let instead of before)
  • shown you that you've only specified a failing case, and not tested for the positive case (or other cases)

If you write the positive case and that passes too then you really know something is wrong!