测试功能包含API请求

时间:2017-11-03 09:47:33

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

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

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-我读了很多关于什么时候使用双精度和存根以及我理解的是什么时候函数没有完成,但是如果函数已经实现了我应该使用双精度来避免类似调用API的函数吗?

1 个答案:

答案 0 :(得分:1)

首先是:

  • 不要为bank_account创建双精度。
  • 不要模拟/存根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调用。