Fl4m3Ph03n1x
Wrong unused warnings in Elixir
Background
I have a test that defines modules which use a behaviour. To save some typing I am using an alias for the behaviour module when I use it in my tests. However the compiler doesn’t see it and plasters my screen with unused warnings.
Code
defmodule MyApp.DispatcherTest do
use ExUnit.Case
# Contract
alias MyApp.Dispatcher.Backend
# SUT
alias MyApp.Dispatcher
test "calls request_fn with the correct parameters" do
defmodule MyApp.Dispatcher.Backend.MissTest do
@behaviour Backend
@impl Backend
def match(_params), do: false
@impl Backend
def url(_params), do: "/bfg_division"
end
defmodule MyApp.Dispatcher.Backend.HitTest do
@behaviour Backend
@impl Backend
def match(_params), do: true
@impl Backend
def url(_params), do: "/family_jules"
end
defmodule MyApp.Dispatcher.Backend.HitTest2 do
@behaviour Backend
@impl Backend
def match(_params), do: true
@impl Backend
def url(_params), do: "/comatose"
end
params = %{}
test_pid = self()
deps = [
backends: [
MyApp.Dispatcher.Backend.HitTest,
MyApp.Dispatcher.Backend.HitTest2,
MyApp.Dispatcher.Backend.MissTest
],
request: fn(name, url) ->
send(test_pid, {:fire, {name, url}})
{:ok, :received}
end
]
Dispatcher.send(params, deps)
expected_name = :hit_test
expected_url = "/family_jules"
assert_receive {:fire, {^expected_name, ^expected_url}}
expected_name2 = :hit_test2
expected_url2 = "/comatose"
assert_receive {:fire, {^expected_name2, ^expected_url2}}
end
end
Inside the test I have 3 test modules (MissTest, HitTest, HitTest2), which implement the behaviour Backend. Each module implements 2 functions to comply with the contract of the behaviour.
Problem
The problem is that every time I run mix test I get this warning plastered onto my screen:
warning: unused alias Backend
test/myapp/dispatcher_test.exs:4
Which is not true. To prove it, if I actually remove the line alias MyApp.Dispatcher.Backend then I get even more warnings, stating that behaviour Backend doens’t exist or is not specified.
Questions
- Why am I getting this warning?
- How can I fix it?
Marked As Solved
josevalim
This is a (non-solvable) limitation in how the compiler detects that aliases are used. Once that file is compiled, the Backend has indeed not been used, because the other modules are only defined (and their contents only executed) when the test runs.
You have two options:
- Pass
warn: falseto the alias - Move your module definition outside of the test and inside the module body
Also Liked
zwippie
I guess this is what’s happening:
You are defining your test backend modules within MyApp.DispatcherTest, so their final name is something like MyApp.DispatcherTest.MyApp.Dispatcher.Backend.MissTest, not MyApp.Dispatcher.Backend.MissTest.
Fl4m3Ph03n1x
Thank you so much for your reply.
One final question.
Does this mean, in your opinion, that I am using a anti-pattern in my tests? Am I structuring my code so bad that I am hitting a compiler limitation? (Does this raise any flags to you?)
josevalim
I personally don’t think it is a bad flag, it is fine. But you can also move the modules out and the behaviour should be the same, so I would rather do that rather than use the warn: false flag, if that makes any sense.
Popular in Questions
Other popular topics
Categories:
Sub Categories:
Forums
Popular Tags
- #ecto
- #liveview
- #troubleshooting
- #learning-elixir
- #deployment
- #library
- #erlang
- #testing
- #genserver
- #mix
- #absinthe
- #remote-other
- #otp
- #plug
- #how-to-question
- #macros
- #postgres
- #channels
- #elixirconf
- #exunit
- #discussion
- #code-sync
- #javascript
- #podcasts
- #onsite
- #dialyzer
- #docker
- #authentication
- #umbrella
- #full-time-contract
- #podcasts-by-brainlid
- #ecto-query
- #elixir-ls
- #phoenix_html
- #iex
- #blog-post
- #graphql
- #genstage
- #ai
- #websockets
- #supervisor
- #advent-of-code
- #elixirconf-us
- #distillery
- #processes
- #forms
- #api
- #metaprogramming
- #security
- #performance








