ruby-on-rails-3 – 如何使用factory_girl模拟和存储活动记录before_create回调

前端之家收集整理的这篇文章主要介绍了ruby-on-rails-3 – 如何使用factory_girl模拟和存储活动记录before_create回调前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我有一个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

厂:

#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

我不知道如何将rspec模拟和存根帮助器加载到我的工厂.这可能不是处理这个的最好方法.

解决方法

作为VCR宝石的作者,您可能希望我推荐这样的案例.我确实推荐它来测试与HTTP相关的代码,但我认为您的设计存在一个潜在的问题.不要忘记,TDD(测试驱动型开发)意在成为一种设计规范,当您发现轻松测试某件事情感到痛苦时,就会告诉您有关设计的内容.听你的测试痛!

在这种情况下,我认为您的模式没有业务进行第三方API呼叫.这是违反单一责任原则的重大违法行为.模型应该对某些数据的验证和持续性负责,但这绝对超出了这一点.

相反,我建议您将第三方API调用移动到观察者中.帕特·马多克斯(Pat Maddox)有一个great blog post讨论观察者如何(而且应该)将它们松散地耦合在一起,而不会违反SRP(单一责任原则),以及如何使测试更容易,并且还可以改善您的设计.

一旦将其移动到观察者中,就可以很容易地禁用单元测试中的观察者(除了该观察者的特定测试除外),但在生产和集成测试中保持启用.您可以使用Pat的no-peeping-toms插件来帮助您,或者如果您使用的是导轨3.1,则应该查看ActiveModel内置的new functionality,它允许您使用easily enable/disable observers.

猜你在找的Ruby相关文章