ruby on rails——一个rspec角色测试失败了,但几乎相同的测试都成功了



我刚刚添加了Rolify gem,并且正在运行一些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

factories.rb

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

为什么第一个测试是失败的nil对象,但第二个是通过?

编辑

进一步检查后,无论添加的角色是否与选中的角色匹配,should be_true的任何测试都通过,should be_false的任何测试都失败。

当您的测试做should be_true时,正在发生的事情是应该调用被委托给主题对象(参见RSpec文档中的隐式接收器)。在本例中,您的主题对象是一个尚未保存到数据库的User实例。如果您的user_spec。rb文件从describe User do开始,RSpec自动提供这个默认的User主题。new(见RSpec文档中的隐式主题).

这意味着你的测试基本上是在做User.new.should be_trueUser.new.should be_false。因为User对象总是求值为true,所以should be_true测试总是会通过(尽管可能不是因为您想要它通过的原因),而应该为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

我假设示例组实际上嵌套在用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

HTH,大卫。

相关内容

  • 没有找到相关文章

最新更新