[英]How would you test observers with rSpec in a Ruby on Rails application?
假设您的Ruby on Rails应用程序中有一个ActiveRecord :: Observer - 如何使用rSpec测试此观察者?
您处于正确的轨道上,但在使用rSpec,观察者和模拟对象时,我遇到了许多令人沮丧的意外消息错误。 当我对我的模型进行规范测试时,我不希望在我的消息期望中处理观察者行为。
在你的例子中,没有一种非常好的方法在模型上规定“set_status”而不知道观察者将对它做什么。
因此,我喜欢使用“No Peeping Toms”插件。 鉴于上面的代码并使用No Peeping Toms插件,我会像这样指定模型:
describe Person do
it "should set status correctly" do
@p = Person.new(:status => "foo")
@p.set_status("bar")
@p.save
@p.status.should eql("bar")
end
end
你可以指定你的模型代码,而不必担心会有一个观察者会进来并破坏你的价值。 您可以在person_observer_spec中单独指定,如下所示:
describe PersonObserver do
it "should clobber the status field" do
@p = mock_model(Person, :status => "foo")
@obs = PersonObserver.instance
@p.should_receive(:set_status).with("aha!")
@obs.after_save
end
end
如果你真的想要测试耦合的Model和Observer类,你可以这样做:
describe Person do
it "should register a status change with the person observer turned on" do
Person.with_observers(:person_observer) do
lambda { @p = Person.new; @p.save }.should change(@p, :status).to("aha!)
end
end
end
99%的时间,我宁愿在关闭观察员的情况下进行规范测试。 这样更简单。
免责声明:我从来没有真正在生产网站上做过这个,但看起来合理的方式是使用模拟对象, should_receive
和朋友,并直接在观察者上调用方法
鉴于以下模型和观察者:
class Person < ActiveRecord::Base
def set_status( new_status )
# do whatever
end
end
class PersonObserver < ActiveRecord::Observer
def after_save(person)
person.set_status("aha!")
end
end
我会写一个这样的规格(我跑了,它通过了)
describe PersonObserver do
before :each do
@person = stub_model(Person)
@observer = PersonObserver.instance
end
it "should invoke after_save on the observed object" do
@person.should_receive(:set_status).with("aha!")
@observer.after_save(@person)
end
end
no_peeping_toms现在是一个宝石,可以在这里找到: https : //github.com/patmaddox/no-peeping-toms
如果要测试观察者是否观察到正确的模型并按预期接收通知,则以下是使用RR的示例。
your_model.rb:
class YourModel < ActiveRecord::Base
...
end
your_model_observer.rb:
class YourModelObserver < ActiveRecord::Observer
def after_create
...
end
def custom_notification
...
end
end
your_model_observer_spec.rb:
before do
@observer = YourModelObserver.instance
@model = YourModel.new
end
it "acts on the after_create notification"
mock(@observer).after_create(@model)
@model.save!
end
it "acts on the custom notification"
mock(@observer).custom_notification(@model)
@model.send(:notify, :custom_notification)
end
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.