Ruby on rails Rspec验证带有额外验证错误的测试失败的唯一性

Ruby on rails Rspec验证带有额外验证错误的测试失败的唯一性,ruby-on-rails,ruby-on-rails-3,rspec,factory-bot,shoulda,Ruby On Rails,Ruby On Rails 3,Rspec,Factory Bot,Shoulda,我在我的答案模型上有两个作用域唯一性验证,我正在尝试使用Rspec和相应的shoulda匹配器来测试它们 如下面的测试跟踪中所示,唯一性验证消息存在于错误数组中,但是,还存在2个,有时还有3个其他错误“正文不能为空(nil)”,“正文太短(至少10个字符)(nil)”,“用户id不能为空(nil)”。我不确定它们来自哪里,因为body和user属性是在before块中显式设置的 我如何更正这些额外的错误,以便唯一性测试能够通过 答案.rb validates_uniqueness_of

我在我的答案模型上有两个作用域唯一性验证,我正在尝试使用Rspec和相应的shoulda匹配器来测试它们

如下面的
测试跟踪中所示,唯一性验证消息存在于错误数组中,但是,还存在2个,有时还有3个其他错误<代码>“正文不能为空(nil)”,“正文太短(至少10个字符)(nil)”,“用户id不能为空(nil)”
。我不确定它们来自哪里,因为body和user属性是在before块中显式设置的

我如何更正这些额外的错误,以便唯一性测试能够通过

答案.rb

    validates_uniqueness_of :correct, scope: :question_id, if: :correct?, message: "You can only have 1 correct answer per question"
    validates_uniqueness_of :user_id, scope: :question_id, message: "Only 1 answer per question per user"

    /* omitted for brevity */
回答_spec.rb

require "spec_helper"

describe Answer do  
  before(:each) do
    @user1 = create(:user)
    @answer = create(:answer, correct: true, user_id: @user1.id, body: "some text which is over 10 chars long")
  end

  subject { @answer }

  it { should respond_to(:user_id) }
  it { should respond_to(:question_id) }
  it { should respond_to(:body) }
  it { should respond_to(:correct)}
  it { should respond_to(:votes_count)}
  it { should respond_to(:points)}
  it { should belong_to(:question)}
  it { should belong_to(:user)}
  it { should have_many(:activities)}
  it { should have_many(:comments)}
  it { should have_many(:votes)}
  it { should validate_uniqueness_of(:correct).scoped_to(:question_id).with_message("correct You can only have 1 correct answer per question (true)") }
  it { should validate_uniqueness_of(:user_id).scoped_to(:question_id).with_message("user_id Only 1 answer per question per user (1)") }

/* omitted for brevity */
测试痕迹

  1) Answer 
     Failure/Error: it { should validate_uniqueness_of(:correct).scoped_to(:question_id).with_message("correct You can only have 1 correct answer per question (true)") }
       Expected errors to include "correct You can only have 1 correct answer per question (true)" when correct is set to true, got errors: ["body can't be blank (nil)", "body is too short (minimum is 10 characters) (nil)", "user_id can't be blank (nil)", "correct You can only have 1 correct answer per question (true)"]
     # ./spec/models/answer_spec.rb:20:in `block (2 levels) in <top (required)>'

  2) Answer 
     Failure/Error: it { should validate_uniqueness_of(:user_id).scoped_to(:question_id).with_message("user_id Only 1 answer per question per user (1)") }
       Expected errors to include "user_id Only 1 answer per question per user (1)" when user_id is set to 1, got errors: ["body can't be blank (nil)", "body is too short (minimum is 10 characters) (nil)", "user_id Only 1 answer per question per user (1)"]
     # ./spec/models/answer_spec.rb:21:in `block (2 levels) in <top (required)>'

Finished in 1.31 seconds
17 examples, 2 failures

它失败是因为你没有测试@answer。你没有在这些测试中定义你的主题。因此,它使用rspec的
主题
,默认情况下,它将成为您所描述的任何类的新实例,即
Answer.new
。您需要显式地将主题设置为@answer,或者显式地测试@answer

describe Answer do
  it { should validate_uniqueness_of(:correct).scoped_to(:question_id).with_message("correct You can only have 1 correct answer per question (true)") }
  it { should validate_uniqueness_of(:user_id).scoped_to(:question_id).with_message("user_id Only 1 answer per question per user (1)") }
end

它失败是因为你没有测试@answer。你没有在这些测试中定义你的主题。因此,它使用rspec的
主题
,默认情况下,它将成为您所描述的任何类的新实例,即
Answer.new
。您需要显式地将主题设置为@answer,或者显式地测试@answer

describe Answer do
  it { should validate_uniqueness_of(:correct).scoped_to(:question_id).with_message("correct You can only have 1 correct answer per question (true)") }
  it { should validate_uniqueness_of(:user_id).scoped_to(:question_id).with_message("user_id Only 1 answer per question per user (1)") }
end

嗨,Philip,这确实是有道理的,我最初在测试中就有这个,但是替换它,不幸的是似乎并没有消除错误。我在这个问题上加了一个主题。如果直接测试@answer会发生什么
@answer.should…
Hi Philip,这确实有道理,我最初在测试中使用了它,但很遗憾,替换它似乎并没有消除错误。我在这个问题上加了一个主题。如果直接测试@answer会发生什么<代码>@answer.应该…