如何测试after_initialize轨道模型的回调?

MMo*_*ore 8 rspec ruby-on-rails rspec2 rspec-rails ruby-on-rails-3

我正在使用FactoryGirl和Rspec进行测试.如果为零,则模型在init之后设置外键.因此它使用另一个关联的数据.但我怎么测试呢?通常我会使用工厂来创建这个对象,并使用stub_chain作为"self.user.main_address.country_id".但是在创建此对象后,将调用initialize.我没有机会把它留下来.

after_initialize do
  if self.country_id.nil?
    self.country_id = self.user.main_address.country_id || Country.first.id
  end
end
Run Code Online (Sandbox Code Playgroud)

任何的想法?

Orl*_*ndo 10

理想情况下,测试行为而不是实现更好.测试是否设置了外键而不是测试该方法是否被调用.

虽然,如果你想在after_initialize这里测试回调是一种有效的方法.

obj = Model.allocate
obj.should_receive(:method_here)
obj.send(:initialize)
Run Code Online (Sandbox Code Playgroud)

Allocate将对象放入内存但不调用initialize.设置期望后,可以调用initialize并捕获方法调用.

  • 此方法似乎不再适用于 Rails 6 和 rspec-rails 4.0.2。它抛出“无法代理冻结对象,rspec-mocks 依赖于方法存根和期望的代理。”。@Yoopergeek 的新答案确实有效。 (2认同)

Yoo*_*eek 6

奥兰多的方法是有效的,这是另一个我想补充的方法.(使用新的rspec'expect'语法)

expect_any_instance_of(Model).to receive(:method_here)
Model.new
Run Code Online (Sandbox Code Playgroud)