2

我一直在试图找出一种方法来测试以下代码(在 Elixir 中):

 defmacro __using__(_) do 
      quote do
        # API functions will be used from this client
        import Client.API 

        def list_storages do
          case list_buckets do
            {:ok, res} ->
              case res.status_code do
                200 ->
                  res.body
                  |> Friendly.find("name")
                  |> Enum.map(fn bucket -> bucket.text end)
                _   ->
                  res |> show_error_message_and_code
              end
            {:error, reason} ->
              parse_http_error reason
          end
        end
  ...

问题是该list_buckets功能是从Client.API模块中导入的(已经在另一个项目中进行了测试,我在那里无法真正改变任何东西)。我的想法是对 API 函数进行存根/模拟/虚拟化,以便它们只返回一个虚拟回复。我尝试使用defoverridable覆盖该list_buckets函数,但这不起作用,因为函数定义发生在另一个模块中。

我已经阅读了 José Valim 的以下帖子,这有助于测试 Client.API 模块,但我没有找到将这些概念应用于这个特定问题的方法。

到目前为止,我唯一(也是愚蠢)的想法是在测试文件中重新实现宏中的每个函数并使用在那里定义的虚拟 API 函数,但如果非测试代码中有代码更改,那感觉非常错误并且没有帮助。

基本上我想测试三种可能的情况是否正确:

  1. 接收{:ok, res}和编码200-> 输出正确的数据
  2. 接收{:ok, res}和另一个代码 -> 输出错误消息和代码
  3. 接收{:error, reason}-> 解析 HTTP 错误并输出失败原因

谁能帮我这个?

4

1 回答 1

0

您仍然可以使用该博客文章中的原则。而不是导入Client.Api将其作为最后一个变量传递给list_storages.

def list_storages(api \\ Client.Api) do
  case api.list_buckets do

这样,您无需更改应用程序代码中的任何内容,并且可以在测试函数时传递虚拟模拟。

于 2016-05-12T06:31:31.197 回答