给定一个典型的ActiveRecord模型,我经常会有before_save
个回调来解析输入,例如从用户那里获取类似time_string
的内容并将其解析为time
字段。
该设置可能如下所示:
before_save :parse_time
attr_writer :time_string
private
def parse_time
time = Chronic.parse(time_string) if time_string
end
我知道将回调方法设为私有是最佳做法。但是,如果它们是私有的,那么你就不能单独调用它们来单独测试它们。
所以,对于经验丰富的Rails测试人员来说,你如何处理测试这类事情?
答案 0 :(得分:9)
在Ruby中,私人方法仍然可以通过Object#send
您可以将其用于单元测试,如下所示:
project = Project.new
project.time_string = '2012/11/19 at Noon'
assert_equal(project.send(:parse_time), '2012-11-19 12:00:00')
答案 1 :(得分:3)
我要做的是保存对象的new
或build
实例的状态,保存对象并根据{更改的属性值进行断言或期望{1}}
before_save
这样您就可以测试对象应该如何操作的行为,而不一定是方法的实现。
答案 2 :(得分:0)
我的回调有时会出现if
条件,在这种情况下我会使用run_callbacks
。
before_save :parse_time, :if => Proc.new{ |post| post.foo == 'bar' }
通过
进行了积极测试post = Post.new
post.foo = 'bar'
expected_time = Chronic.parse(post.time_string)
post.run_callbacks :before_save
assert_equal(post.time, expected_time)
和否定
post = Post.new
post.foo = 'wha?'
post.run_callbacks :before_save
assert_nil(post.time)