我正在尝试使用 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/