RSpec和Rails 3 -简单的测试失败



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

我正在做一些简单的测试,以确保用户注册时是有效的。失败的测试是"应该要求用户名"。结果错误是:

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

正如你所看到的,我只是用一个空的用户名创建一个新用户(还没有使用工厂,只是简单的测试),因为validates_presence_of :username它应该有错误。

我错过了什么?

由于您在模拟框架中使用Mocha,因此需要告诉Rspec这一点(仅将Mocha放在Gemfile中是不够的)。在你的spec_helper.rb文件中,修改如下:

config.mock_with :rspec

:

config.mock_with :mocha

你所有的测试都会通过。


更多信息:

你的User模型规格实际上工作得很好,如果你自己运行它:

rspec spec/models/user_spec.rb

你的UsersController规范实际上是一个干扰,这就是为什么在你的整个项目中运行rspec失败。

您的控制器规格先于您的模型规格运行。在您的控制器规格中,您有几个User.any_instance.stub...调用。你最后的UsersController规格证明valid?是真的。这些不仅适用于您的控制器规格。一旦你达到你的User模型规范,调用valid?仍然返回true,因为这个存根,因为Rspec不知道你在使用Mocha。

你需要添加

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

否则不执行验证,因此没有错误。

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

改变:

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?}

罪魁祸首实际上是您的users_controller_spec,该行是:

User.any_instance.stubs(:valid?).returns(true)

相关内容

  • 没有找到相关文章

最新更新