代码之家  ›  专栏  ›  技术社区  ›  Amro Abdalla

测试函数包含API请求

  •  0
  • Amro Abdalla  · 技术社区  · 6 年前

    我试图测试我的rails应用程序,它使用Stripe API,所以我从模型开始,我使用Rspec,我想测试的模型叫做bank_account。rb内部有一个名为(create\u bank\u account)的函数,带有参数(bank\u 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\u bank\u account函数,我伪造了它,所以我的问题是:

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

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

    1 回复  |  直到 6 年前
        1
  •  1
  •   Tom Lord    6 年前

    首先:

    • 不要为创建double 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调用。