Reputation: 1051
I want to be able to doctest the implementation of a protocol in Elixir.
Here is some example code:
defprotocol Size do
def size(data)
end
defmodule Foo do
defstruct []
defimpl Size do
@doc """
## Examples
iex> Size.size(%Foo{})
0
"""
def size(foo) do
0
end
end
end
This test code doesn't work (because it only finds functions defined in the Foo
module, outside of the defimpl
):
ExUnit.start()
defmodule FooTest do
use ExUnit.Case
doctest Foo
end
How can I test the defimpl
block?
Upvotes: 3
Views: 509
Reputation: 407
Prepend the name of the protocol in front of the path. For the given example, it would be:
defmodule FooTest do
use ExUnit.Case
doctest Foo
doctest Size.Foo
end
For the longer example, it's just:
defmodule FooTest do
use ExUnit.Case
doctest MyModule.Foo
doctest Size.MyModule.Foo
end
Per Valim: https://groups.google.com/g/elixir-lang-talk/c/zNMFKOA-I7c
Upvotes: 0
Reputation: 1051
It turns out that defimpl
defines a module behind the scenes. This can be found via the impl_for
function on the protocol:
iex(1)> Size.impl_for(%Foo{})
Size.Foo
So we can doctest this module like so:
defmodule FooTest do
use ExUnit.Case
doctest Foo
doctest Size.Foo
end
Note that if both Size
and Foo
are in the same module (say MyModule
), the module name must be specified twice:
defmodule FooTest do
use ExUnit.Case
doctest MyModule.Foo
doctest MyModule.Size.MyModule.Foo
end
Upvotes: 4