【问题标题】:Elixir - How can you use an alias in doctest?Elixir - 如何在 doctest 中使用别名?
【发布时间】:2017-08-31 17:32:20
【问题描述】:

有没有办法在文档测试中使用模块别名?我不想每次都输入一个长名字。

defmodule SomeLongModuleName.SubModule do
  alias SomeLongModuleName.SubModule, as: SubModule

  @doc """
      iex> SubModule.method(%{property_a: 1, property_b: 2) # CompileError
      3
  """
  def method(%{property_a: a, property_b: b) do
    a + b
  end
end

上面的示例显示了我可能希望使用别名来避免长行的情况。是否可以在 doctest 中使用别名?

【问题讨论】:

  • 我假设 doctests 从全局命名空间运行,所以它不能看到别名。

标签: testing elixir


【解决方案1】:

不完全是您所要求的,但是一种相对干净的方法,无论您如何调用 doctest 都可以工作(不依赖于 import 并且导入函数和现有函数之间没有冲突) - 为 doctest 本身中的模块起别名。

defmodule Some.Long.Module.Chain.Foo
  @doc """
      iex> alias Some.Long.Module.Chain.Foo
      iex> Foo.bar(1)
      "one"
      iex> Foo.bar(2)
      "two"
  """
  def bar(i) do
    # ...
  end
end

【讨论】:

    【解决方案2】:

    基于 lab419 和 dylanthepiguy 的答案:

    带有 doctest 的模块:

    defmodule SomeLongModuleName.SubModule do
      @doc """
          iex> SubModule.add(x, y)
          3
      """
      def add(x, y) do
        x + y
      end
    end
    

    带有doctest的模块测试用例:

    defmodule SomeLongModuleName.SubModuleTest do
      use ExUnit.Case, async: true
    
      # Alias the submodule so we don't have to use the fully qualified name 
      alias SomeLongModuleName.SubModule
    
      doctest SomeLongModuleName.SubModule, import: true
    end
    

    【讨论】:

      【解决方案3】:

      正如 dylanthepiguy 所提到的,将别名放入测试文件中绝对是一个更好的解决方案,就在 doctest 行之前。

      为测试编写代码是恕我直言,代码异味。

      另请注意,as: Submodule 是默认设置,因此没有必要。

      【讨论】:

        【解决方案4】:

        有两种方法我可以想到不必一次又一次地输入模块名称。

        1. 在您的文档中使用插值并使用别名:

          defmodule SomeLongModuleName.SubModule do
            alias SomeLongModuleName.SubModule, as: SubModule
          
            @doc """
                iex> #{SubModule}.method(%{property_a: 1, property_b: 2})
                3
            """
            def method(%{property_a: a, property_b: b}) do
              a + b
            end
          end
          
        2. 仅使用不带模块的函数名称,并在您从测试中调用doctest 时,添加import: true

          defmodule SomeLongModuleName.SubModule do
            @doc """
                iex> method(%{property_a: 1, property_b: 2})
                3
            """
            def method(%{property_a: a, property_b: b}) do
              a + b
            end
          end
          
          doctest SomeLongModuleName.SubModule, import: true
          

        【讨论】:

        • 不错!第一个选项看起来像一个(相当简洁的)hack,而第二个选项看起来正是为这种情况而设计的。也许换个顺序?
        【解决方案5】:

        事实证明,您可以在测试前添加alias SomeLongModuleName.SubModule, as: SubModule 行。

        更好的解决方案是不要在文档中放置太多测试,也不使用别名。然后,在您的测试文件中,您可以将alias SomeLongModuleName.SubModule, as: SubModule 保存。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多