Один тест ролей rspec завершается неудачно, но почти идентичные тесты проходят успешно

Я только что добавил гем Rolify и запускаю несколько тестов rspec.

2 теста заключаются в следующем:

  describe "roles" do

    before(:each) do
      @user = FactoryGirl.create(:user)
    end

    it "should not approve incorrect roles" do
      @user.add_role :moderator
      @user.has_role? :admin
      should be_false
    end

    it "should approve correct roles" do
      @user.add_role :moderator
      @user.has_role? :moderator
      should be_true
    end

  end

Результат теста:

  1) User roles should not approve incorrect roles
     Failure/Error: should be_false
       expected: false value
            got: #<User id: nil, email: "", encrypted_password: "", reset_password_token: nil, reset_password_sent_at: nil, remember_created_at: nil, sign_in_count: 0, current_sign_in_at: nil, last_sign_in_at: nil, current_sign_in_ip: nil, last_sign_in_ip: nil, confirmation_token: nil, confirmed_at: nil, confirmation_sent_at: nil, name: nil, position: nil, location: nil, admin: false, archived: false, public_email: false, created_at: nil, updated_at: nil>
     # ./spec/models/user_spec.rb:70:in `block (3 levels) in <top (required)>'

Finished in 1.37 seconds
7 examples, 1 failure

Failed examples:

rspec ./spec/models/user_spec.rb:67 # User roles should not approve incorrect roles

Randomized with seed 13074

заводы.рб

FactoryGirl.define do

  factory :user do
    sequence(:name)       {|n| "Example User #{n}"}
    sequence(:email)      {|n| "email#{n}@program.com" }
    position              "Regular"
    location              "Anywhere, USA"
    public_email          false
    password              "foobar"
    password_confirmation "foobar"
    confirmed_at          Time.now
  end
end

Как первый тест не работает с нулевым объектом, а второй проходит?

ИЗМЕНИТЬ

При дальнейшей проверке любой тест для should be_true проходит успешно, а любой тест для should be_false не проходит, независимо от того, соответствует ли добавленная роль проверенной роли.


person dewyze    schedule 25.12.2012    source источник
comment
Вы уверены, что секунда проходит?   -  person Said Kaldybaev    schedule 25.12.2012
comment
Ага, посчитал. Пробовал менять порядок, пробовал делать это без FactoryGirl и только User.create([@attr]), и со всеми этими тестами все равно один тест прошел, а другой провалился.   -  person dewyze    schedule 25.12.2012
comment
Я тоже пробовал, should_not be_true и должно быть _nil, но все равно делал то же самое.   -  person dewyze    schedule 25.12.2012


Ответы (2)


Когда ваши тесты выполняют should be_true то, что происходит, вызов должен делегироваться объекту-субъекту (см. документы RSpec для неявного получателя). В этом случае ваш предметный объект является экземпляром пользователя, который еще не был сохранен в базе данных. Если ваш файл user_spec.rb начинается с describe User do, RSpec автоматически предоставляет эту тему User.new по умолчанию (см. документы RSpec для неявной темы).

Это означает, что ваши тесты, по сути, выполняют User.new.should be_true и User.new.should be_false. Поскольку объект User всегда будет оцениваться как true, тест should be_true всегда будет проходить (хотя, вероятно, не по той причине, по которой вы этого хотели), а must be_false всегда будет терпеть неудачу.

Судя по тому, как написаны ваши тесты, возможно, вы имели в виду что-то вроде этого:

describe "roles" do

  before(:each) do
    @user = FactoryGirl.create(:user)
  end

  it "should not approve incorrect roles" do
    @user.add_role :moderator
    @user.has_role?(:admin).should be_false
  end

  it "should approve correct roles" do
    @user.add_role :moderator
    @user.has_role?(:moderator).should be_true
  end

end
person cbascom    schedule 25.12.2012
comment
Спасибо! Я полностью пропустил это. - person dewyze; 25.12.2012

Я предполагаю, что примерная группа на самом деле вложена в группу, объявленную с помощью describe User do, да?

Проблема в том, что последняя строка каждого примера читается как should xxx, но should не имеет приемника, поэтому RSpec заменяет вам экземпляр User.

Что вы хотите:

describe User do
  describe "roles" do
    before(:each) do
      @user = FactoryGirl.create(:user)
    end

    it "should not approve incorrect roles" do
      @user.add_role :moderator
      @user.has_role?(:admin).should be_false
    end

    it "should approve correct roles" do
      @user.add_role :moderator
      @user.has_role?(:moderator).should be_true
    end
  end
end

ХТХ, Дэвид

person David Chelimsky    schedule 25.12.2012
comment
Вау... совсем пропустил. Спасибо!! Кроме того, я где-то видел ответ от вас на другой вопрос, спасибо за то, что это было. При этом, поскольку вы оба одновременно ответили на вопрос одним и тем же ответом, как мне решить, какой из них выбрать? - person dewyze; 25.12.2012
comment
ответ cbascom более подробный, чем мой. Я бы пошел с этим. - person David Chelimsky; 25.12.2012