本文介绍了Rspec validates_uniqueness_of测试失败,并带有其他验证错误的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在回答模型上有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测试失败,并带有其他验证错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

10-20 19:47