alex88

alex88

Compilation order during tests

I’m trying to mock ExTwitter during tests, I’m using GitHub - dashbitco/mox: Mocks and explicit contracts in Elixir · GitHub 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 main · 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 main · dashbitco/mox · GitHub should call Code.ensure_compiled? instead.

Last Post!

hassan

hassan

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

Running mix hex.outdated every so often surfaces those things :slight_smile:

Where Next?

Popular in Questions Top

JeremM34
Hello, how can I check the Phoenix version ? Thanks !
New
vegabook
I’m brand new to Phoenix and I have stripped one of the demo applications to the bone. I just want to get an svg up on the screen. Here i...
New
openscript
Hello! Sorry for this astonishing simple question, but I’m really stuck. I try to set up the intellij-elixir plugin, but I don’t know ho...
New
aalberti333
As the title describes, I’m trying to run Enum.map() over a list of key/value pairs, where the value is a map. My data looks like this: ...
New
pmjoe
I have a relationship of love and hate with Elixir. Lots of things are just absolutely right, but there are some things that are kind of ...
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
dblack
I’ve got an issue with an app and I’ve no idea of how to troubleshoot it. I’m hoping someone here might have seen something similar. I p...
New

Other popular topics Top

KronicDeth
Elixir plugin for JetBrain’s IntelliJ Platform (including Rubymine) This is a plugin that adds support for Elixir to JetBrains IntelliJ...
289 36689 110
New
hariharasudhan94
I would like to know what is the best IDE for elixir development?
New
jononomo
For some reason my phoenix channels are working for me in my local dev environment, but as soon as I deploy via Docker, I get a 403 error...
New
joeerl
Hello again - after a longish gap I’ve decided I really must dig into Elixir and see what’s been happening here - so I have a few questio...
New
romenigld
I am trying to run a deploy with docker and I successfully runned with this command: docker build -t romenigld/blog-prod . but when I t...
New
AstonJ
Posting this to see if we can make things easier for people to get into Neovim. If you use Neovim and have a favourite distro please let ...
New

We're in Beta

About us Mission Statement