【问题标题】:elixir mock inner function url requestelixir mock 内部函数 url 请求
【发布时间】:2018-04-02 16:59:55
【问题描述】:

我如何模拟类似于 python requests-mock 工作方式的特定 api 调用:

with requests_mock.mock() as m:
    m.get('http://test.com', text='data')
    requests.get('http://test.com').text

在此示例中,with 语句中对 http://test.com 的每次调用都会被模拟

例如,在长生不老药中,我有这个:

defmodule API do

  # makes a call to an external API I dont want to test
  def make_call do
    ...
  end
end

defmodule Item do

  alias API

  # function I actually want to test
  def build_request do
    API.make_call
    # stuff I want to test
  end

end

假设我想测试build_request 模拟make_call

我试过这个包https://github.com/jjh42/mock,但是这个包的作用是覆盖整个API模块,例如make_call方法的模拟,但你也失去了API模块的所有其他功能,我不想那样。

我怎么能模拟那个调用?

在另一个例子中,我看到了https://hashrocket.com/blog/posts/mocking-api-s-with-elixir

# mocking a github api call directly
@github_api.make_request(:get, "/users/#{username}")

但这是同一个问题,它直接在测试中模拟请求,我的问题是当模拟需要在 inner 函数中完成时不是马上。

【问题讨论】:

    标签: testing mocking elixir


    【解决方案1】:

    Dependency injection是你的朋友:

    def build_request(caller \\ API) do
      caller.make_call
      # stuff I want to test
    end
    

    并且在测试中,您为调用 build_request 提供一个参数:

    build_request(TestAPI)
    

    有关详细信息,请参阅 José Valim 的 brilliant writing

    【讨论】:

    • 当您可以使用 DI 时这很好,但是如果您依赖 BIF 产生的副作用怎么办(在 OTP 应用程序入口点的 start/2 函数中找到的设置将是一个很好的例子)?
    • @Charlie 我不确定我是否遵循。可以举个例子吗?
    • def start(_type, _args) do start_link([], [strategy: :one_for_one, name: :root]) end 我的意思是,也许我在测试这个时尝试做错了,事实上,我想我可以运行这个函数,并且只测试在依赖树。但如果我确实想监视 start_link/2,我有什么选择?
    • 我怀疑我理解测试def foo(), do: bar() 的目的确实调用bar()(如果没有,nothing 工作,)但依赖注入仍然是你最好的朋友:为您的测试声明一个专用子句def start(_type, mock: true), do: Test.start_link()) 并在那里测试您想要的任何内容。
    猜你喜欢
    • 2011-12-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-10-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多