如何模拟和存根活动记录before_create回调factory_girl [英] How to mock and stub active record before_create callback with factory_girl

查看:92
本文介绍了如何模拟和存根活动记录before_create回调factory_girl的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个ActiveRecord模型,PricePackage。具有before_create回调。此回调,使用第三方API来进行远程连接。我使用的工厂女孩​​,想stub这个API,以便在测试远程调用过程中建立新的工厂都不能进行。

I have an ActiveRecord Model, PricePackage. That has a before_create call back. This call back uses a 3rd party API to make a remote connection. I am using factory girl and would like to stub out this api so that when new factories are built during testing the remote calls are not made.

我使用Rspec的进行嘲弄和存根。我遇到的问题是,Rspec的方法不可用我的factories.rb在

I am using Rspec for mocks and stubs. The problem i'm having is that the Rspec methods are not available within my factories.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

我不知道怎么去装入到我factories.rb RSpec的嘲弄和存根助手,这可能不是处理这一问题的最佳途径。

I'm not sure how to get the rspec mock and stub helpers loaded into my factories.rb and this might not be the best way to handle this.

推荐答案

随着VCR的宝石的作者,你可能希望我推荐它这样的情况下。我的确推荐它是测试HTTP相关的code,但我想有一个与你的设计的根本问题。不要忘了,TDD(测试驱动开发),就是要设计的纪律,当你发现它痛苦的轻松测试的东西,这就是告诉你一些关于你的设计。听你的测试的痛苦!

As the author of the VCR gem, you'd probably expect me to recommend it for cases like these. I do indeed recommend it for testing HTTP-dependent code, but I think there's an underlying problem with your design. Don't forget that TDD (test-driven development) is meant to be a design discipline, and when you find it painful to easily test something, that's telling you something about your design. Listen to your tests' pain!

在这种情况下,我认为你的模型没有业务使得第三方API调用。这是一个pretty的显著违反了单一职责原则。模型应该是负责一些数据的有效性和持久性,但肯定这已经超出了这一点。

In this case, I think your model has no business making the 3rd party API call. It's a pretty significant violation of the single responsibility principle. Models should be responsible for the validation and persistence of some data, but this is definitely beyond that.

相反,我建议您将第三方API调用成观察员。帕特·马多克斯有href="http://patmaddox.com/blog/better-rails-testing-decoupling-observers.html" rel="nofollow">精彩的博客帖子讨论一个

Instead, I would recommend you move the 3rd party API call into an observer. Pat Maddox has a great blog post discussing how observers can (and should) be used to loosely couple things without violating the SRP (single responsibility principle), and how that makes testing, much, much easier, and also improves your design.

一旦你感动的是成为一个观察者,它很容易禁用单元测试的观察者(除了为观察员的具体测试),但保持它在生产和集成测试启用。您可以使用帕特的没有偷窥 - 汤姆斯的插件来解决这个问题,或者,如果你重上轨道3.1,你应该检查出的<一个href="https://github.com/rails/rails/blob/v3.1.0/activemodel/lib/active_model/observer_array.rb#L18-39"相对=nofollow>新内置于加载ActiveModel功能,让您<一个href="https://github.com/rails/rails/blob/v3.1.0/activemodel/lib/active_model/observer_array.rb#L18-39"相对=nofollow>轻松地启用/禁用观察家。

Once you've moved that into an observer, it's easy enough to disable the observer in your unit tests (except for the specific tests for that observer), but keep it enabled in production and in your integration tests. You can use Pat's no-peeping-toms plugin to help with this, or, if you're on rails 3.1, you should check out the new functionality built in to ActiveModel that allows you to easily enable/disable observers.

这篇关于如何模拟和存根活动记录before_create回调factory_girl的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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