Ruby on Rails:我的所有ActiveRecord回调方法都应该是私有的吗?

krn*_*krn 6 activerecord rspec ruby-on-rails

我有一个ActiveRecord模型,它有一些我想测试的回调和自定义验证.这意味着,我必须将所有这些公开.这是一个好的做法还是在这种情况下有更好的解决方案?

我想测试的方法示例:

  def before_validation
    original.edit(self) if original
  end

  validate :unique?, on: :create

  def unique?
    return true if original.blank?
    errors.add(:base, 'The entry already exists')
    false
   end
Run Code Online (Sandbox Code Playgroud)

换一种说法:

  1. 如果我想测试"before_validation"方法,我是否必须将其公开并直接在我的模型Rspec文件中调用test_object.before_validation?
  2. 如果我不仅要测试,那个自定义验证方法是唯一的?()是在验证时调用的,而且,方法本身,我是否还必须公开唯一的?()?

问题是,我在模型之外使用的这些方法都没有(因此它们应该是私有的),但是如何在不公开的情况下进行测试?

MrD*_*anA 3

很容易陷入测试实施的困境,但这是测试行为的一个很好的候选者。

问问自己,你在验证之前到底在做什么?然后给自己做一个测试,在给定某些输入的情况下,当且仅当您的前验证有效时,您才会得到某些输出。

举一个简单的例子,假设您有一个具有简单name属性的用户模型,并且您有一个 before_validation ,它的作用很简单:

name = "Auto-generated name." if name.blank?
Run Code Online (Sandbox Code Playgroud)

然后你可以为它编写一个测试,如下所示:

it "gets an auto-generated name if none is specified." do
    user = User.create!
    user.name.should eq "Auto-generated name."
end

it "does not get an auto-generated name if one is specified." do
    user = User.create!(:name => "Test Name")
    user.name.should eq "Test Name"
end
Run Code Online (Sandbox Code Playgroud)

正如您所看到的,此测试确实测试了验证,但不需要将其公开,因为您只是测试它的行为。你的方法也是如此unique?。为其提供某些输入并测试其行为,而无需关心使用了哪种特定方法或任何其他实现细节。