简体   繁体   中英

Rails unit test failing

The following User test passes with no problem, the user is valid:

user_test.rb:

require 'test_helper'

class UserTest < ActiveSupport::TestCase

  def setup
    @user = User.new(name: "Example User", email: "user@example.com", callsign: "example",
                     password: "foobar", password_confirmation: "foobar")
  end

  test "user should be valid" do
    assert @user.valid?
  end
end

User model:

class User < ActiveRecord::Base

  attr_accessor :remember_token, :activation_token, :reset_token

  has_many :personas, dependent: :destroy
  has_secure_password

  before_save do
    email.downcase!
    callsign.downcase!
  end
  before_create :create_activation_digest

  validates :name, presence: true,
                   length: { maximum: 50 }
  VALID_EMAIL_REGEX = /\A[\w+\-.]+@[a-z\d\-]+(?:\.[a-z\d\-]+)*\.[a-z]+\z/i
  validates :email, presence:   true,
                    format:     { with: VALID_EMAIL_REGEX },
                    uniqueness: { case_sensitive: false }
  VALID_CALLSIGN_REGEX = /\A[a-z\d\-.\_]+\z/i
  validates :callsign, presence:   true,
                       length:     { maximum: 20 },
                       format:     { with: VALID_CALLSIGN_REGEX },
                       uniqueness: { case_sensitive: false }
  validates :password, length: { minimum: 6 }, allow_blank: true

  def to_param
    callsign
  end
  .
  .
end

However, when I set up exactly the same user in the persona_test, the validation fails. (The persona validation fails too, each User has_many personas)

persona_test.rb:

require 'test_helper'

class PersonaTest < ActiveSupport::TestCase

  def setup
    @user = User.new(name: "Example User", email: "user@example.com", callsign: "example",
                       password: "foobar", password_confirmation: "foobar")
    @persona = @user.personas.build(name: "Bazman", callsign: "Baz")
  end

  test "user should be valid" do
    assert @user.valid?
  end

  test "persona should be valid" do
    assert @persona.valid?
  end
end

Persona model:

class Persona < ActiveRecord::Base

  belongs_to :user

  before_save do
    self.callsign.downcase!
    set_persona_id
  end

  validates :name, presence: true,
                   length:   { maximum: 50 }
  VALID_CALLSIGN_REGEX = /\A[a-z\d\-.\_]+\z/i
  validates :callsign, presence:   true,
                       length:     { maximum: 20 },
                       format:     { with: VALID_CALLSIGN_REGEX },
                       uniqueness: { case_sensitive: false }
  validates :user_id, presence: true
  validates :persona_id, presence: true

  def to_param
    callsign
  end
  .
  .
end

Failed test output:

FAIL["test_user_should_be_valid", PersonaTest, 0.754914]
test_user_should_be_valid#PersonaTest (0.75s)
Failed assertion, no message given.
test/models/persona_test.rb:18:in `block in <class:PersonaTest>'

FAIL["test_persona_should_be_valid", PersonaTest, 0.893247]
test_persona_should_be_valid#PersonaTest (0.89s)
Failed assertion, no message given.
test/models/persona_test.rb:22:in `block in <class:PersonaTest>'

I don't understand why the User validation in persona_test.rb is failing when the setup user is identical to the one in user_test.rb. Are you not allowed to test Users in a Personas test? If so, how do I successfully test personas? Each persona belongs_to a user, so I have to create a user in order to create a persona.

EDIT:

persona_test.rb:

require 'test_helper'

class PersonaTest < ActiveSupport::TestCase

  def setup
    @user = User.new(name: "Example User", email: "user@example.com", callsign: "example",
                       password: "foobar", password_confirmation: "foobar")#, activated: true)
    @persona = @user.personas.build(name: "Bazman", callsign: "Baz")
    @persona.user = @user
    @persona.persona_id = 1
  end

  test "user should be valid" do
    assert @user.valid?, @user.errors.full_messages
  end

  test "persona should be valid" do
    assert @persona.valid?, @persona.errors.full_messages
  end
end

With the updated persona test above, I get the error message 'User can't be blank'. Why is

@persona.user = @user

not working?

In your persona model you have:

  validates :user_id, presence: true
  validates :persona_id, presence: true

But it doesn't look like a user_id is being set. Try setting it with @persona.user = @user in your test.

Additionally, as a tool for debugging, you can print @persona.errors.full_messages in your test to see where exactly it is not validating.

Eg assert @persona.valid?, @persona.errors.full_messages

Hope that helps.

EDIT : as per the comments below, the line should actually be @persona.user_id = @user.id . Another way you could achieve the same effect is to actually save the records to the database. So in your setup function, you would use create instead of build . This would, however, be slower.

The reason for the failed assertion is that some validations in Persona won't pass:

validates :user_id, presence: true
validates :persona_id, presence: true

The validations are run before saving them to the database. For new records, user_id and persona_id will still be nil .

Because Persona is invalid, the User will be invalid in the other test as well.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM