woohaaha

woohaaha

How to mock unit tests but not integration tests? (Using Mox ideally)

I’m trying to wrap my head around using mocks in Elixir. There are a lot of blog posts on the subject but I’m not seeing any that address my use cases.

(no need to recommend http://blog.plataformatec.com.br/2015/10/mocks-and-explicit-contracts/, read it a few times :wink:)

To be a bit more specific, here are my scenarios/questions:

I would like my integration tests to write-to/read-from the database. I don’t want my unit tests to touch the database. I’d like to use a mock for the persistence layer. How can I do this with Mox? It seems all the examples require one into an all-or-nothing commitment. You’re either using the DB or not.

On dependency injection… I don’t mind injecting a mock Repo in my unit tests but I don’t understand how that scales into intermediary modules when I have to test those. For example:

defmodule MyApp.Accounts do
  def list_users(repo \\ MyApp.Repo) do
    repo.all(User)
  end
end

defmodule MyApp.Dashboard do
  # do i inject MyApp.RepoMock here? i'd need to DI all these functions. how do i test with mocks in this context?
  # def get_the_world(repo \\ MyApp.Repo) <---- ???
  def get_the_world() do
    so_many_users = MyApp.Accounts.list_users(repo)
    MyApp.AnotherContext.more_stuff_to_mock_stub(MyApp.DI1)
    MyApp.Context3.yup_more_goes_here(MyApp.DI2)
     ...
  end
end

Would appreciate it if someone can explain how I can use Mox in unit tests and not in integration tests. Would also like to know how DI works without having to pass modules through multiple layers just to have precise control in my unit tests.

Thank you :nerd_face:

Most Liked

ityonemo

ityonemo

  1. Use Mox.
  2. For your unit tests, do the normal Mox thing.
  3. For your integration tests, use stub_with and stub out to the unmocked module, this will make a database call.
  4. read up on how to make Ecto tests async.
rodrigues

rodrigues

Hi @woohaaha, in https://hexdocs.pm/mox you can see how to set a mock using application env as dependency injection:

Application.put_env(:my_app, :calculator, MyApp.CalcMock)

You can have some tests doing that, while other tests use the non-mocked implementation:

Application.put_env(:my_app, :calculator, MyApp.RealCalculator)

To see how to do this in ex_unit, you can take a look at setup and ExUnit.CaseTemplate.

axelson

axelson

Scenic Core Team

I was suggesting that you could use the Application.put_env approach for all your integration tests and mark them as async: false. But I’d second @ityonemo’s approach of using Mox.stub_with in your integration tests. That will work for most cases as long as you aren’t spawning additional processes.

ityonemo

ityonemo

I should be careful. What I mean is “always always use Task instead of a naked spawn or spawn_link”. If you don’t need async (most of the time you don’t), don’t use a Task.

skylerparr

skylerparr

Use syringe https://github.com/skylerparr/syringe allows you to mock pretty much anything.

Where Next?

Popular in Questions Top

freewebwithme
Using vs code and installed ElixirLS: support and debugger. And I got an error popped up on start up says Failed to run ‘elixir’ comma...
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
gshaw
What is the idiomatic way of matching for not nil in Elixir? E.g., First way: defp halt_if_not_signed_in(conn, signed_in_account) when...
New
joaquinalcerro
Hi there, I am working with Ecto-Postgresql and I need to call all of the records from a specific table but the table has 40,000 record...
New
hariharasudhan94
I would like to know what is the best IDE for elixir development?
New
tduccuong
Hi, is there any work on GUI with Elixir, that is similar to Electron/Javascript? My idea is to bundle Phoenix and BEAM into a single se...
New
quazar
How to set Jason to encode all fields in ecto schema, I don’t care about security and implementing only is taking long list of attributes...
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
gonzofish
I’m currently trying to understand how to join three tables using Ecto. All the examples I’ve seen use 2, so maybe I’m just missing somet...
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

Other popular topics Top

belgoros
I’m not a pro in using Regex and can’t figure out why the following behaviour happens, especially if we take into account the difference ...
New
9mm
I am constructing a JSON object (map) and I need to conditionally set a field. I’m trying to write proper elixir-way code… and I’m at a l...
New
stefanchrobot
What’s the safe way to decode a JSON string into a struct? I want to avoid calling String.to_atom. Jason.decode can give me a map with st...
New
josevalim
Hi everyone, One of the features added to Elixir early on to help integration with Erlang code was the idea of overridable function defi...
New
senggen
Erlang/OTP 25 [erts-13.2.2] [source] [64-bit] [smp:8:8] [ds:8:8:10] [async-threads:1] 15:22:35.803 [error] gen_event {lager_file_backend...
New
dokuzbir
Hello, I am trying to convert my lists to string without losing brackets.For start i have 3 map. They look like these buyer = %{ id: ...
New
vertexbuffer
Hello, can anybody help here..? I have a list of players and I what to delete an element, but every for loop the list is reverting to ori...
New
stefanluptak
Hello everybody, usually, I use a 29" ultra-wide monitor for VSCode which can easily accomodate explorer (files panel) + file with code ...
New
ovidiubadita
Hey all, I discovered Elixir and I love it. I always wanted to learn a functional programming and I intended to go for Haskell, but afte...
New
Fl4m3Ph03n1x
About me? ( if you have nothing better to do than reading about some random guy in the internet :stuck_out_tongue: ) Hello all, this is ...
New

We're in Beta

About us Mission Statement