6

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

4

3 回答 3

10

在 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')
于 2012-12-19T21:45:16.250 回答
4

我要做的是保存对象newbuild实例的状态,保存对象并根据被更改的属性的值做出断言或期望before_save

post = Post.new
post.time_string = '2012/11/19'
expected_time = Chronic.parse(post.time_string)
post.save
assert_equal(post.time, expected_time)

这样,您正在测试对象应该如何操作的行为,而不一定是方法的实现。

于 2012-12-19T21:54:18.967 回答
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)

有关更多详细信息,请参阅API博客

于 2016-06-03T01:22:03.947 回答