ruby-on-rails - 测试函数包含 API 请求

标签 ruby-on-rails ruby testing stripe.net

我正在尝试使用 Stripe API 测试我的 Rails 应用程序,所以我从模型开始,我正在使用 Rspec,我要测试的模型称为 bank_account.rb,其中有一个函数称为 (create_bank_account ) 与参数 (bank_token) 它的伪代码是这样的:

def create_bank_account(bank_token)
  # make a Stripe request and save it in local variable
  # save needed data in my bank_account table in my DB
end

当我开始测试这个功能时,我发现它里面有一个API调用,这不好,我需要我的测试不依赖于互联网,所以搜索后我找到了'StripeMock` gem,它很有用我开始将它与 Rspec 一起使用,但我发现自己正在编写这样的测试:

it 'with valid bank_token` do
  # create a double for bank_account
  # using StripeMock to get a faked response for creating
  # new bank_account
  # expect the doube to receive create_bank_account
  # function and response with saving the data inside the DB
end

但在写完这篇文章后我注意到我实际上并没有运行 create_bank_account 函数我伪造了它,所以我的问题是:

1- 我如何测试包含 API 请求的函数但运行它自己的函数而不是伪造它?

2- 我读了很多关于何时使用 double 和 stub 的信息,我的理解是当函数未完成时,但如果函数已经实现,我是否应该使用 double 来避免调用 API 之类的函数?

最佳答案

首要的是:

  • 不要为 bank_account 创建双重身份。
  • 不要模拟/ stub bank_account.create_bank_account

如果您在应该测试 BankAccount#create_bank_account 行为的测试中执行这些操作中的任何一个,那么您的测试就毫无值(value)。

(为了证明这一点,尝试在该方法中编写损坏的代码。您的测试显然应该失败。但是如果您模拟该方法,一切都会通过!!)

不管怎样,您应该模拟stripe 请求,即您的应用程序和互联网之间边界 处的行为.

如果没有更多信息,我无法提供工作代码示例,但从广义上讲,您可以从此重构代码:

def create_bank_account(bank_token)
  # make a Stripe request and save it in local variable
  # save needed data in my bank_account table in my DB
end

对此:

def create_bank_account(bank_token)
  stripe_request = make_stripe_request(bank_token)
  # save needed data in my bank_account table in my DB
end

private

def make_stripe_request(bank_token)
  # ...
end

...然后在您的测试中,您可以 use StripeMock 伪造 BankAccount#make_stripe_request 的响应。

如果代码不是那么容易重构(?!),那么像这样直接 stub Stripe 库可能不切实际。您可以随时采用的另一种方法是使用像 webmock 这样的库简单地拦截所有 HTTP 调用。

关于ruby-on-rails - 测试函数包含 API 请求,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47092690/

相关文章:

java - Junit 4 全局设置和拆卸

api - HTTP 响应生成器网络服务

ruby-on-rails - 用于多用户 Tumblr 克隆的 CakePHP、CodeIgniter 或 Rails?

ruby-on-rails - rails 3.1 has_many :through extra field in join model

ruby-on-rails - 在这部分代码中设置 klass = self 的动机是什么

ruby-on-rails - 当 Rails 重新加载类时,初始化程序中的 Controller 猴子补丁丢失

android - 比较 Appium 和 MonkeyTalk 之间用于 Android 应用程序测试的工具

ruby-on-rails - Mongoid 发现不起作用?

ruby-on-rails - 如何在 Arel 中将单个绑定(bind)变量设为 "resuse"?

ruby - 调用父类的初始化函数?