【发布时间】:2015-12-30 18:02:41
【问题描述】:
TL;DR 我想知道我是否可以测试使用查询的模型方法(即find、where)无需将测试对象持久化到数据库。
所以我是 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