【问题标题】:Elixir: Redefine module in testElixir:在测试中重新定义模块
【发布时间】:2017-02-11 02:53:51
【问题描述】:

我有一个 ping 端点的 ExUnit 测试。该端点调用一个函数,该函数通过由环境a la Jose Valim's famous post 确定的http 客户端进行外部调用。

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

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

我也尝试使用 mock library 执行此操作,这会引发不同的错误,即使我直接模拟 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)

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

【问题讨论】:

  • 据我所知,您无法重新定义这样的模块。您可以发布您使用mock 的代码(如果与此不完全相同,则发布错误消息)?
  • @Dogbert 我已经用mock 版本更新了代码。错误不同。
  • 你能不能也模拟一下:start/0?类似于with_mock HTTPoison, [get: fn(_url) -> {:ok, %HTTPoison.Response{body: []}} end, start: fn() -> end] do
  • @Dogbert 成功了,谢谢。那么,该错误消息具有误导性。为什么说module HTTPoison is not available
  • 哦。我什至没有读过那部分,这就是为什么我建议添加start/0

标签: elixir ex-unit


【解决方案1】:

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

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

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 repo for purge

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-05-30
    • 2016-02-24
    • 1970-01-01
    • 1970-01-01
    • 2017-10-29
    • 2017-02-17
    • 1970-01-01
    • 2016-07-10
    相关资源
    最近更新 更多