如何独立测试模型的回调方法? [英] How to test model's callback method independently?

查看:100
本文介绍了如何独立测试模型的回调方法?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在模型中有一个方法:

I had a method in a model:

class Article < ActiveRecord::Base
  def do_something
  end
end

I也对此方法进行了单元测试:

I also had a unit test for this method:

# spec/models/article_spec.rb
describe "#do_something" do
  @article = FactoryGirl.create(:article)
  it "should work as expected" do
    @article.do_something
    expect(@article).to have_something
  end
  # ...several other examples for different cases
end

一切都很好,直到我发现最好将此方法移到 after_save 回调中:

Everything was fine until I found it's better to move this method into a after_save callback:

class Article < ActiveRecord::Base
  after_save :do_something

  def do_something
  end
end

现在我所有关于此方法的测试都被破坏了。我必须通过以下方式解决它:

Now all my tests about this method broken. I have to fix it by:


  • 没有对 do_something 的更具体的调用,因为 create save 也会触发此方法,否则我将遇到重复的数据库操作。

  • create 更改为 build

  • 测试response_to

  • 使用常规 model.save 代替单个方法调用 model.do_something

  • No more specific call to do_something because create or save will trigger this method as well, or I'll meet duplicate db actions.
  • Change create to build
  • Test respond_to
  • Use general model.save instead of individual method call model.do_something

describe "#do_something" do
  @article = FactoryGirl.build(:article)
  it "should work as expected" do
    expect{@article.save}.not_to raise_error
    expect(@article).to have_something
    expect(@article).to respond_to(:do_something)
  end
end


测试通过了,但我担心的是它不再与特定方法有关。如果添加了更多效果,则该效果将与其他回调混合在一起

The test passed but my concern is it's no longer about the specific method. The effect will be mixed with other callbacks if more added.

我的问题是,有没有什么漂亮的方法可以独立测试成为回调的模型实例方法?

My question is, is there any beautiful way to test model's instance methods independently that becoming a callback?

推荐答案

回调和回调行为是独立的测试。如果要检查after_save回调,则需要将其视为两件事:

Callback and Callback behavior are independent tests. If you want to check an after_save callback, you need to think of it as two things:


  1. 是否针对正确的事件触发了回调?

  2. 被调用函数是否在做正确的事?

假设您有 Article 类,其中包含许多回调,这是您要测试的方式:

Assume you have the Article class with many callbacks, this is how you would test:

class Article < ActiveRecord::Base
  after_save    :do_something
  after_destroy :do_something_else
  ...
end

it "triggers do_something on save" do
  expect(@article).to receive(:do_something)
  @article.save
end

it "triggers do_something_else on destroy" do
  expect(@article).to receive(:do_something_else)
  @article.destroy
end

it "#do_something should work as expected" do
  # Actual tests for do_something method
end

这可以使回调与行为脱钩。例如,当其他相关对象更新时,您可以触发相同的回调方法 article.do_something ,例如 user.before_save {user.article。 do_something}

This decouples your callbacks from behavior. For example, you could trigger the same callback method article.do_something when some other related object is updated, say like user.before_save { user.article.do_something }. This will accomodate all those.

因此,请像往常一样继续测试您的方法。

So, keep testing your methods as usual. Worry about the callbacks separately.

编辑:错别字和潜在的误解
编辑:将做某事更改为触发某事

typos and potential misconceptions change "do something" to "trigger something"

这篇关于如何独立测试模型的回调方法?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆