kev*_*ler 17 activerecord mocking rspec-rails ruby-on-rails-3 factory-bot
我有一个ActiveRecord模型,PricePackage.这有一个before_create回调.此回调使用第三方API进行远程连接.我正在使用工厂女孩,并希望将这个api存根,以便在测试期间建立新工厂时不会进行远程调用.
我正在使用Rspec进行模拟和存根.我遇到的问题是我的工厂中没有Rspec方法.rb
模型:
class PricePackage < ActiveRecord::Base
has_many :users
before_create :register_with_3rdparty
attr_accessible :price, :price_in_dollars, :price_in_cents, :title
def register_with_3rdparty
return true if self.price.nil?
begin
3rdPartyClass::Plan.create(
:amount => self.price_in_cents,
:interval => 'month',
:name => "#{::Rails.env} Item #{self.title}",
:currency => 'usd',
:id => self.title)
rescue Exception => ex
puts "stripe exception #{self.title} #{ex}, using existing price"
plan = 3rdPartyClass::Plan.retrieve(self.title)
self.price_in_cents = plan.amount
return true
end
end
Run Code Online (Sandbox Code Playgroud)
厂:
#PricePackage
Factory.define :price_package do |f|
f.title "test_package"
f.price_in_cents "500"
f.max_domains "20"
f.max_users "4"
f.max_apps "10"
f.after_build do |pp|
#
#heres where would like to mock out the 3rd party response
#
3rd_party = mock()
3rd_party.stub!(:amount).price_in_cents
3rdPartyClass::Plan.stub!(:create).and_return(3rd_party)
end
end
Run Code Online (Sandbox Code Playgroud)
我不确定如何将rspec模拟和存根助手加载到我的factories.rb中,这可能不是处理此问题的最佳方法.
Myr*_*ton 20
作为VCR宝石的作者,你可能希望我推荐它用于这样的案例.我的确推荐它用于测试依赖于HTTP的代码,但我认为你的设计存在潜在的问题.不要忘记TDD(测试驱动开发)是一个设计学科,当你发现轻松测试某些东西很痛苦时,它会告诉你一些关于你的设计的东西.听听你的测试的痛苦!
在这种情况下,我认为您的模型没有进行第三方API调用的业务.这是对单一责任原则的严重违反.模型应该负责某些数据的验证和持久性,但这肯定超出了这个范围.
相反,我建议您将第三方API调用移动到观察者.Pat Maddox有一篇很棒的博客文章,讨论观察者如何(而且应该)在不违反SRP(单一责任原则)的情况下松散地结合事物,以及如何使测试变得更加容易,并且还可以改进您的设计.
一旦你感动,为观察员,这是很容易禁用单元测试的观察者(除了为观察员的具体测试),但保持它在生产和集成测试启用.你可以使用Pat的no-peeping-toms插件来帮助解决这个问题,或者,如果你在rails 3.1上,你应该检查一下ActiveModel内置的新功能,它允许你轻松启用/禁用观察者.
| 归档时间: |
|
| 查看次数: |
6293 次 |
| 最近记录: |