测试函数包含一个 API 请求

Testing function contains an API request

我正在尝试测试我的 rails 应用程序,它使用 Stripe APIs,所以我从模型开始,我正在使用 Rspec,我想要的模型test 被称为 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-我读了很多关于何时使用双打和存根的内容,我的理解是当函数未完成时,但如果函数已经实现,我是否应该使用双打来避免调用 APIs?

首先也是最重要的:

  • 不要为 bank_account 创建替身。
  • 不要mock/stub bank_account.create_bank_account.

如果您在应该测试BankAccount#create_bank_account行为的测试中执行了其中任何一项操作,那么您的测试就毫无价值。

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

无论如何,你应该嘲笑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.

的响应

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