RSpec and Rails 3 - Simple tests do not work

RSpec 2.5, Rails 3.0.6 - git: //github.com/stevecastaneda/project.git

I am doing some simple tests to make sure users are valid at registration. A test that fails should "require a username". Received error:

Failure/Error: new_user(:username => '').should have(1).error_on(:username) expected 1 error on :username, got 0 

user_spec.rb

 require File.dirname(__FILE__) + '/../spec_helper' describe User do def new_user(attributes = {}) attributes[:username] ||= 'foo' attributes[:email] ||= ' foo@example.com ' attributes[:password] ||= 'abc123' attributes[:password_confirmation] ||= attributes[:password] User.new(attributes) end before(:each) do User.delete_all end it "should be valid" do new_user.should be_valid end it "should require username" do new_user(:username => '').should have(1).error_on(:username) end end 

User.rb

 class User < ActiveRecord::Base # new columns need to be added here to be writable through mass assignment attr_accessible :username, :email, :password, :password_confirmation attr_accessor :password before_save :prepare_password validates_presence_of :username validates_uniqueness_of :username, :email, :allow_blank => true validates_format_of :username, :with => /^[-\w\ ._@ ]+$/i, :allow_blank => true, :message => "should only contain letters, numbers, or .-_@ " validates_format_of :email, :with => /^[-a-z0-9_+\.]+\@([-a-z0-9]+\.)+[a-z0-9]{2,4}$/i validates_presence_of :password, :on => :create validates_confirmation_of :password validates_length_of :password, :minimum => 4, :allow_blank => true # login can be either username or email address def self.authenticate(login, pass) user = find_by_username(login) || find_by_email(login) return user if user && user.password_hash == user.encrypt_password(pass) end def encrypt_password(pass) BCrypt::Engine.hash_secret(pass, password_salt) end private def prepare_password unless password.blank? self.password_salt = BCrypt::Engine.generate_salt self.password_hash = encrypt_password(password) end end end 

As you can see, I'm just creating a new user (not using only factories, just simple tests) with an empty username, and due to validates_presence_of :username it should have errors.

What am I missing?

+4
source share
3 answers

Since you are using Mocha for your breadboard framework, you need to say Rspec (just putting Mocha in your Gemfile is not enough). In your spec_helper.rb file change this:

 config.mock_with :rspec 

For this:

 config.mock_with :mocha 

and all your tests will pass.


Additional Information:

Your User model specification actually works fine if you run it yourself:

 rspec spec/models/user_spec.rb 

Your UsersController specification is actually interfering, so rspec for the entire project.

The specifications of your controller run before your model specifications. There are several calls to User.any_instance.stub... in the specifications of your controller. Latest UsersController spec stubs valid? must be true. They are not tied only to your controller specifications. Once you click on your User Model Specification, are calls valid? still return true due to this interrupt since rspec does not know that you are using mocha.

+2
source

You need to add

 user = new_user(:username => '') user.should_not be_valid 

Otherwise, the check is not performed, and therefore there are no errors.

Works for me:

 require 'active_model' def new_user(attributes = {}) attributes[:username] ||= 'foo' attributes[:email] ||= ' foo@example.com ' attributes[:password] ||= 'abc123' attributes[:password_confirmation] ||= attributes[:password] User.new(attributes) end class User include ActiveModel::Validations attr_accessor :username, :email validates_presence_of :username end describe User do it "should validate" do new_user(:username => '').should_not be_valid end end 

Change this:

 validates_format_of :username, :with => /^[-\w\ ._@ ]+$/i, :allow_blank => true, :message => "should only contain letters, numbers, or .-_@ " 

:

 validates_format_of :username, :with => /^[-\w\ ._@ ]+$/i, :message => "should only contain letters, numbers, or .-_@ ", :unless => lambda {|u| u.username.blank?} 
+1
source

In fact, the culprit is your users_controller_spec, and the line is:

 User.any_instance.stubs(:valid?).returns(true) 
+1
source

All Articles