0

我有一个 ping 端点的 ExUnit 测试。该端点调用一个函数,该函数通过一个由环境确定的 http 客户端进行外部调用,例如 la Jose Valim 的著名帖子

在测试环境中,我使用的是 HTTPoison 的模拟模块。

defmodule HTTPoisonMock do
  def get(_url), do: raise "You need to define this function for your test"
end

在测试本身中,我试图重新定义这个模块,以便该函数返回一个预设响应。

test "/my_endpoint" do
  defmodule HTTPoisonMock do
    def get(_url) do
      {:ok, %HTTPoison.Response{body: []}}
    end
  end

  conn = conn(:get, "/my_endpoint")
  ...

  assert conn.status == 200
end

但是,未使用重新定义的模块。运行测试时出现原始错误。

** (ArgumentError) You need to define this function for your test

我也尝试使用模拟库来执行此操作,这会引发不同的错误,即使我直接模拟 HTTPoison 也是如此。

require HTTPoison

test "/my_endpoint" do
  with_mock HTTPoison, [:get, fn(_url) -> {:ok, %HTTPoison.Response{body: []}} end] do
    conn = conn(:get, "/my_endpoint")

    ...

    assert conn.status == 200
  end
end

** (UndefinedFunctionError) function HTTPoison.start/0 is undefined (module HTTPoison is not available)

为什么没有使用我重新定义的模块?

4

1 回答 1

3

看来问题已经解决了,但我会为未来的访客回答最初的问题。

要重新定义测试中的模块,可以:

test "/my_endpoint" do
  Code.eval_string """
    defmodule HTTPoisonMock do
      def get(_url) do
        {:ok, %HTTPoison.Response{body: []}}
      end
    end
  """

  # do stuff

  after
    purge HTTPoisonMock
  end
end

这在 Elixir 核心测试中大量使用,grep 用于purge.

于 2017-02-10T18:53:51.123 回答