简体   繁体   中英

Elixir - How can you use an alias in doctest?

Is there a way to use a module alias in the doctests? I don't want to have to type out a long name every single time.

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

The example above shows a situation where I might want to use the alias to avoid long lines. Is it at all possible to use an alias in a doctest?

There are two ways I can think of to not have to type the module name again and again.

  1. Use interpolation in your docs and use the aliased name:

     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. Use just the function name without module and in your call to doctest from your tests, add 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

Building on the answer from lab419 and dylanthepiguy:

Module with doctest:

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

Test case for module with 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

It turns out you can put a alias SomeLongModuleName.SubModule, as: SubModule line just before the test.

A better solution is to not put too many tests in the docs, and not use an alias. Then, in your test file you can put alias SomeLongModuleName.SubModule, as: SubModule to save.

As mentioned by dylanthepiguy it is definitely a better solution to put the aliases into the testfile, just before the doctest line.

Instrumenting your code for tests is IMHO a code smell.

Also note that as: Submodule is the default and therefore unnecessary.

Not exactly what you're asking for, but one approach that is relatively clean and will work regardless of how you invoke doctest (doesn't rely on the import and the lack of conflicts between imported and existing functions) - alias the module in the doctest itself.

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM