首页 文章

RSpec和Rails 3 - 简单测试失败

提问于
浏览
4

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 它应该有错误 .

我错过了什么?

3 回答

  • 1

    由于你正在使用Mocha作为你的模拟框架,你需要告诉Rspec这个(只是将Mocha放在你的_1392018中是不够的) . 在 spec_helper.rb 文件中,更改以下内容:

    config.mock_with :rspec
    

    对此:

    config.mock_with :mocha
    

    并且所有测试都将通过 .


    More Info:

    你的 User 模型规范实际上工作正常,如果你自己运行它:

    rspec spec/models/user_spec.rb
    

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

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

  • 1

    你需要添加

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

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

    适合我:

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

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

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

相关问题