Rails:如何测试before_save回调

时间:2012-12-19 21:40:51

标签: ruby-on-rails testing private-members

给定一个典型的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测试人员来说,你如何处理测试这类事情?

3 个答案:

答案 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)

我要做的是保存对象的newbuild实例的状态,保存对象并根据{更改的属性值进行断言或期望{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)

有关详细信息,请参阅the APIa blog