alex88

alex88

Compilation order during tests

I’m trying to mock ExTwitter during tests, I’m using https://github.com/plataformatec/mox for that.

In my code I use a config variable to do the Dependency Injection, like this:

config :my_app,
  # DI
  twitter_client: MyApp.TwitterClient

I’ve defined my mock in test/support/mocks.ex as per Mox docs like this

Mox.defmock(MyApp.Mocks.TwitterClient, for: MyApp.TwitterClient)

and in my test.exs config I have

config :my_app,
  # DI
  twitter_client: MyApp.Mocks.TwitterClient

Everything worked while incrementally compiling during development, however on a fresh checkout without any _build folder i get this error:

== Compilation error in file test/support/mocks.ex ==
** (ArgumentError) module MyApp.TwitterClient is not available, please pass an existing module to :for
    lib/mox.ex:92: Mox.validate_behaviour!/1
    lib/mox.ex:84: Mox.defmock/2
    (elixir) lib/kernel/parallel_compiler.ex:121: anonymous fn/4 in Kernel.ParallelCompiler.spawn_compilers/1

if I remove that mock line, compile and add the line back everything works. It seems like it’s trying to compile the mock file first and then the lib folder.

My elixirc_paths is ["lib", "test/support", "test/factories"] so lib comes first, any idea?

I’ve pushed a sample app with the problem in https://github.com/alex88/myapp just run mix test

Marked As Solved

ericmj

ericmj

Elixir Core Team

If you call Mox.defmock at compile time, which you do if you put it in the body of a file covered by elixirc_paths, then the function will call Code.ensure_loaded? at compile time. You will see that if you follow the stacktrace leading up to mox/lib/mox.ex at master · dashbitco/mox · GitHub. Calling Code.ensure_loaded? at compile is not safe because it’s a race to check if the module is loaded. If you instead call Code.ensure_compiled? then the compiler will wait until the given module is compiled, it works similar to require. You will notice that it works if you add a call to Code.ensure_compiled? before the call to Mox.defmock.

Also Liked

hubertlepicki

hubertlepicki

I figured it out why it works for me. I have 3 apps in umbrella, and I only mock the interactions where one calls another. So I suppose in my case the clean build works since the app I am about to mock is already always fully compiled (is in_umbrella dependency).

hubertlepicki

hubertlepicki

Thank you both @alex88 for reporting the issue and @ericmj for finding the solution <3

ericmj

ericmj

Elixir Core Team

Yes, modules will be compiled in the correct based on the calls or requires that is made in compile time. If you call a module at compile time the calling module will wait until the callee is compiled.

If it’s supposed to be supported to define behaviour implementations* at compile time then I think this line mox/lib/mox.ex at master · dashbitco/mox · GitHub should call Code.ensure_compiled? instead.

alex88

alex88

Just as reference for readers, the pull request @hubertlepicki openend that includes the fix is https://github.com/plataformatec/mox/pull/17

ciroque

ciroque

Turns out the real solution was to upgrade the version :wink:
Didn’t realize I had pinned it at 0.1.0 (C&P from web page, DOH)

Where Next?

Popular in Questions Top

Harrisonl
We have an ECS cluster with 4 services, where each task joins a single cluster, via discovery ECS discovery service. Currently when I de...
New
jerry
Good day to you all. I have been struggling to get a query involving like and ilike to work. Can anyone assist me on this, please? pro...
New
itssasanka
Hi all, Trying to get some more clarity over utc_datetime and naive_datetime for Ecto: https://hexdocs.pm/ecto/Ecto.Schema.html#module-...
New
pgiesin
This should be a simple problem but I just can’t seem to figure it out. I have a standalone Elixir app that won’t find the database. Dep...
New
New
nsuchy
Hi. I’ve noticed that Windows Powershell has it’s own IEX command and you cannot access Elixir’s IEX due to the conflict. This isn’t a cr...
New
mcarvalho
What is the difference between System.get_env and Application.get_env? For example, what are best practices to use one versus another.
New
Phillipp
Hey, I have a NanoPi-M3 and try to install Elixir on their Ubuntu image. I followed the Raspberry Pi installation instructions from the ...
New
hpopp
To simplify some tasks at work, I wrote and published this package yesterday. It’s a simple macro that enables Access behaviour on struct...
New
siddhant3030
Hi, I have to write a raw query for one of my project. But till now I have used ecto queries and don’t have much experience writing raw ...
New

Other popular topics Top

lanycrost
Hi everyone! I need implement if…else if…else condition from my elixir code, and anymore of this control flow structures not work proper...
New
minhajuddin
I have seen a lot of code which picks the first element from a list using Enum.at(0) instead of List.first. Is there a reason why people ...
New
Harrisonl
We have an ECS cluster with 4 services, where each task joins a single cluster, via discovery ECS discovery service. Currently when I de...
New
vrod
I am using the Starship cross-shell prompt – it seems pretty nice, but I get some errors: [WARN] - (starship::utils): Executing command ...
New
axelson
This post is a wiki (feel free to hit the edit button near the bottom right of this post to add your own changes!) This post collects co...
239 45766 226
New
vonH
When I run the Plug and I recompile I wind up having to use Ctrl C to quit iex and start again. Witht the help of rlwrap I can use the cu...
New
lucidguppy
I have a super simple question about elixir - how would I take a file like this foo bar baz and output a new file that enumerates th...
New
AstonJ
by Lance Halvorsen Elixir and Phoenix are generating tremendous excitement as an unbeatable platform for building modern web application...
460 27162 124
New
jay1
Why is it that the mnesia database isn’t the most preferred database for use in Elixir/Phoenix?
New
magnetic
Hey :wave:t3: Elixir community, I’ve been learning Elixir, and working on some side projects. My editor of choice is VSCode, and althoug...
New

We're in Beta

About us Mission Statement