如何独立测试模型的回调方法? [英] How to test model's callback method independently?
问题描述
我在模型中有一个方法:
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
becausecreate
orsave
will trigger this method as well, or I'll meet duplicate db actions. - Change
create
tobuild
- Test respond_to
Use general
model.save
instead of individual method callmodel.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:
- 是否针对正确的事件触发了回调?
- 被调用函数是否在做正确的事?
假设您有 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屋!