Rspec检查记录的存在和值

时间:2014-01-13 05:42:47

标签: ruby-on-rails rspec

我想测试是否存在User模型属性。 所以我这样写。

describe "Authentications" do
  it "sign up with twitter" do
    visit new_user_session_path
    expect { click_link "Sign up with Twitter"}.to change(User, :count).by(1)
  end
  describe "new user" do
    let(:new_user) { User.last }
    it "should have slug" do
      #new_user its(:slug) { should eq("foo") }
      new_user.slug should exist
    end
  end
end

首次测试通过,但第二次测试失败,出现此错误。

  1) Authentications new user should have slug
     Failure/Error: new_user.slug should exist
     NoMethodError:
       "new user" does not respond to either #exist? or #exists?
     # ./spec/features/autentication_spec.rb:13:in `block (3 levels) in <top (required)>'

我认为我正在以错误的方式调用方法。我应该如何使用它?

毕竟我不仅要检查它的存在,还要检查它的价值。但它也失败了。

2 个答案:

答案 0 :(得分:6)

如果要验证值的存在,则应使用Rails提供的方法present?

expect(new_user.slug).to be_present应该适用于您想要的效果。

答案 1 :(得分:1)

首先,你所期望的失败等同于:

new_user.slug(subject.should(exist))

这就是为什么你的失败消息引用“新用户”,这是我们的例子的描述,因此是subject的隐含值。

据推测,您打算将should应用于new_user.slug,在这种情况下,您应该写一下:

new_user.slug.should exist

但是,只有当new_user.slug的值定义了exist?方法(每https://www.relishapp.com/rspec/rspec-expectations/v/2-99/docs/built-in-matchers/exist-matcher)时才会出现这种情况,而这些字符串则没有。

如果您想测试某些内容是否只是truthy,那么您可以使用:

new_user.slug.should be

如果您想将false排除为值,则可以使用:

new_user.slug.should_not be_nil

本回答的其余部分涉及一个单独的问题,可能会或可能不会影响您的测试,具体取决于在调用整个User块之前您的数据库中是否有describe

假设您正在使用 on 进行操作,则在您的it块中创建的用户在后续describe的正文中不存在,因此{{1 }}将返回User.first,这可以解释您的错误。

如果您要检查您的登录是否将用户数更改为一个使用该登录进行单独测试,则可以使用nil表达式,如下所示:

let

如果要将这些测试结合起来以便了解slug故障,可以按照以下步骤进行:

describe "Authentications" do
  let(:sign_in) do
    visit new_user_session_path
    click_link "Sign up with Twitter"
  end
  it "sign up with twitter" do
    expect { sign_in }.to change(User, :count).by(1)
  end
  describe "new user" do
    let(:new_user) { User.last }
    before { sign_in }
    it "should have slug" do
      #new_user its(:slug) { should eq("foo") }
      new_user.slug should exist
    end
  end
end