RSpec и Rails 3 - простые тесты не пройдены - PullRequest
4 голосов
/ 28 апреля 2011

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 ]

2 голосов
/ 28 апреля 2011

Поскольку вы используете 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.

1 голос
/ 28 апреля 2011

Фактически виновником является ваш users_controller_spec, а строка:

User.any_instance.stubs(:valid?).returns(true)
1 голос
/ 28 апреля 2011

Вам нужно добавить

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?}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...