【问题标题】:rails unit testing with ActiveRecord associations without hitting the DB使用 ActiveRecord 关联进行 rails 单元测试,而不会影响数据库
【发布时间】:2015-12-30 18:02:41
【问题描述】:

TL;DR 我想知道我是否可以测试使用查询的模型方法(即findwhere无需将测试对象持久化到数据库。

所以我是 Rails 新手,并且正在使用现有的代码库。
我注意到的一件事是,我们的单元测试需要永远才能运行。
经过调查,罪魁祸首当然是我们在测试模型时将所有内容都保存到数据库中。
因此,我开始尝试编写不会影响数据库的模型测试,但我遇到了一个障碍:
当一个模型与其他模型有关联时,对其执行的任何操作都假定所有内容都是持久的。

我们来看一个例子——

class Parent < ActiveRecord::Base
  has_many :children, dependent: :destroy

  def default_child
    children.find_by(default: true)
  end

end

所以我很自然地想测试我的default_child 方法是否有效:

parent = Parent.new
default_child = parent.children.build(default: true)

assert_equal default_child, parent.default_child

但是这个测试失败了,因为parent.default_child的实际结果是nil
这是因为在内部,default_child 方法使用find_by,它似乎只适用于持久对象的上下文。

所以我不得不像这样写测试-

parent = Parent.new
# I don't want to do this!!
parent.save
# why 'create' and not 'build'?
default_child = parent.children.create(default: true)

assert_equal default_child, parent.default_child

哪个更丑更慢。
有什么方法可以在内存中测试这些操作吗?

我尝试手动设置children (parent.children = [ child1, child2 ])。
这不会导致错误,但似乎find_by 不在那里,而是在数据库中......

我看到a similar question 是 3 年前提出的,但没有确定的答案,我想知道从那时起是否有任何变化..

附:奖金问题 - 我可以对 on: update 的验证做些什么?似乎我必须在调用测试对象之前至少保留一次..

【问题讨论】:

    标签: ruby-on-rails ruby-on-rails-3 unit-testing activerecord


    【解决方案1】:

    最后一个问题。对于验证,只需断言模型为 valid?

    parent = Parent.new
    assert parent.valid?
    

    至于他的主要问题,没有很好的答案,人们对如何测试这类事情有不同的看法。我的意见是你应该测试你的业务逻辑,避免测试框架提供给你的功能(大概已经被框架本身包含的测试验证了)。

    我认为您想测试Parent#default_child 背后的业务逻辑(顺便说一句,不应该是default_children 吗?)它只返回与default = true 关联的Child 对象。假设您相信 ActiveRecord 可以正常工作,您可以模拟(您需要添加 Mocha ,或使用类似 RSpec 的东西)find_by(default: true) 始终返回带有要设置的 default 属性的 Child 对象到true。因为你相信ActiveRecord 会为你做这件事。但我不会嘲笑每个ActiveReocrd 方法。你会浪费很多时间,最后也不会很开心。

    对于某些测试,您可能会发现您绝对需要有数据。你可以使用fixtures available in Rails,或者使用FactoryGirl之类的东西

    【讨论】:

    • 是的,我就是这么想的。我可能会去看看模拟 ActiveRecord,尽管我对这个前景并不十分兴奋。顺便说一句,我的最后一个问题是关于 on: update 的验证,所以在这种情况下你的答案将不起作用(parent 需要首先保持)。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-10-04
    • 1970-01-01
    • 1970-01-01
    • 2019-04-01
    • 1970-01-01
    • 2011-12-02
    • 2016-03-22
    相关资源
    最近更新 更多