Rails单元测试失败

时间:2014-12-21 14:23:45

标签: ruby-on-rails unit-testing

以下用户测试通过没有问题,用户有效:

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

用户模型:

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

但是,当我在persona_test中设置完全相同的用户时,验证失败。 (角色验证也失败了,每个用户都有很多人物)

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

女神异闻录模特:

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

测试输出失败:

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>'

我不明白为什么当setup用户与user_test.rb中的用户相同时,persona_test.rb中的用户验证失败。您是否被允许在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")#, 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

通过上面更新的角色测试,我收到错误消息“用户不能为空”。为什么

@persona.user = @user

不工作?

2 个答案:

答案 0 :(得分:1)

在你的角色模型中,你有:

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

但它看起来不像是在设置user_id。尝试在测试中使用@persona.user = @user进行设置。

此外,作为调试工具,您可以在测试中打印@persona.errors.full_messages以查看其未确认的确切位置。

E.g。 assert @persona.valid?, @persona.errors.full_messages

希望有所帮助。

编辑:根据以下评论,该行实际应为@persona.user_id = @user.id。另一种可以实现相同效果的方法是将记录实际保存到数据库中。因此,在您的设置功能中,您将使用create而不是build。然而,这会更慢。

答案 1 :(得分:1)

断言失败的原因是Persona中的某些验证无法通过:

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

在将验证保存到数据库之前运行验证。对于新记录,user_idpersona_id仍为nil

由于Persona无效,User在其他测试中也无效。