Ruby on rails 如何在不假设ActiveRecord::Base方法是如何使用的情况下存根ActiveRecord::Base方法';用过什么?

Ruby on rails 如何在不假设ActiveRecord::Base方法是如何使用的情况下存根ActiveRecord::Base方法';用过什么?,ruby-on-rails,unit-testing,activerecord,stubbing,Ruby On Rails,Unit Testing,Activerecord,Stubbing,ActiveRecord::Base有一个大型的ol'API,它具有多种查找和保存对象的方法。例如,您的AR::B对象可能已从许多方法实例化: Foo.new(…) Foo.create(…) Foo.find(…) Foo.find\u by\u sql(…) Foo.find通过.*(…)查找[所有] bar.foos(关联) …当然,还有关于关联的查找方法 类似地,有问题的对象可能会通过几种不同的方法得到持久化: foo.create或foo.create foo.save或fo

ActiveRecord::Base
有一个大型的ol'API,它具有多种查找和保存对象的方法。例如,您的
AR::B
对象可能已从许多方法实例化:

  • Foo.new(…)
  • Foo.create(…)
  • Foo.find(…)
  • Foo.find\u by\u sql(…)
  • Foo.find通过.*(…)查找[所有]
  • bar.foos
    (关联)
    • …当然,还有关于关联的查找方法
类似地,有问题的对象可能会通过几种不同的方法得到持久化:

  • foo.create
    foo.create
  • foo.save
    foo.save
  • foo.update\u属性
    foo.update\u属性
现在,在编写单元测试时,最好的做法是存根外部方法调用,以便您的测试能够关注所讨论方法的业务逻辑。然而,当涉及到使用
AR::B
对象时——例如在控制器单元测试中——您似乎必须使用上述方法之一,而实际上,就方法的业务逻辑而言,选择哪种方法并不重要


您是否必须将方法的行为与其实现紧密地结合起来,还是我缺少了一些简单的东西?

一种方法是以这样的方式构建类,即在您自己的方法中封装任何
ActiveRecord::Base
方法调用

因此,不要直接调用
Foo.new(…)

class Foo < ActiveRecord::Base
  def self.create_object(…)
    new(…)
  end
end
class Foo
这样,在测试中,您可以删除自己的方法,而不是ActiveRecord的方法

Avdi Grimm在《Rails上的对象》一书中详细介绍了这种方法(包括其“优点”)