问题描述
我在回答模型上有2个范围内的唯一性验证,我正在尝试使用Rspec和相应的Shoulda匹配器进行测试.
如下面的test trace
所示,错误数组中存在唯一性验证消息,但是,还存在2个错误,有时还存在3个其他错误. "body can't be blank (nil)", "body is too short (minimum is 10 characters) (nil)", "user_id can't be blank (nil)"
.我不确定它们的来源,因为body和user属性是在before块中明确设置的.如何纠正这些其他错误,以便唯一性测试通过?
answer.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 */
answer_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
factory.rb
factory :answer do
user
question_id :question
body "you need to change your grip"
votes_count 0
correct false
end
失败,因为您没有测试@answer.您没有在这些测试中定义主题.因此,它使用的是rspec的subject
,默认情况下它将转到您所描述的任何类的新实例,即. 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
I have 2 scoped uniqueness validations on my answer model, I am trying to test these using Rspec and the respective shoulda matchers.
As seen in the test trace
below, the uniqueness validations message is present in the errors array however, there are also 2 and sometimes 3 other errors present; "body can't be blank (nil)", "body is too short (minimum is 10 characters) (nil)", "user_id can't be blank (nil)"
. I'm not sure where they are coming from, as body and user attributes are set explicitly in the before block.
How can I correct these additional errors so the uniqueness test will pass?
answer.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 */
answer_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 */
Test trace
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
factory.rb
factory :answer do
user
question_id :question
body "you need to change your grip"
votes_count 0
correct false
end
It's failing because you're not testing @answer. You're not defining your subject in these tests. So it's using rspec's subject
which by default is going to a new instance of whatever class you're describing, ie. Answer.new
. You either need to explicitly set the subject to @answer or explicitly test @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
这篇关于Rspec validates_uniqueness_of测试失败,并带有其他验证错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!