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 => "testuser@example.com", :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!
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 => "testuser@example.com", :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 ofbefore
) - 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!
精彩评论