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

Tee
can someone please explain to me how Enum.reduce works with maps
New
LegitStack
I’m hoping you guys can give me some general advice and perhaps code examples if you’re feeling up to it. I’m very interested in Elixir,...
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
SoCreat
i’m a new one to elixir which editor can i use vs code? or atom? Thanks! :smiley:
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
johnnyicon
Hi all, I've just started learning Elixir and Phoenix Framework, so please pardon my n00bness at this stage. I'm trying to use Postg...
New
Qqwy
Original source of discussion: This topic on the Pragmatic Programmers' Functional Web Development with Elixir, OTP, and Phoenix forum. ...
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
vrod
I am using the Starship cross-shell prompt – it seems pretty nice, but I get some errors: [WARN] - (starship::utils): Executing command ...
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

Other popular topics Top

dotdotdotPaul
Okay, I'm having a heck of a time trying to figure out how to best handle the validation of belongs_to associations in Ecto. I'm sure I'...
New
albydarned
Hello all! I am typing this post from my new MacBook Pro with the M1 chip. I’m loving it so far, and will probably use it as my daily dr...
New
sergio_101
I am VERY much an elixir newbie. I have taken one elixir course and one phoenix course on Udemy. During that course, I saw the instructor...
New
chrismccord
This release brings a number of exciting features, including integration with the new Phoenix LiveDashboard and Phoenix LiveView. There h...
New
lk-geimfari
What is most correct way to open, read and parse JSON file with poison? For example if we have example.json file in root of some projec...
New
vac
Hi, I'm quite new in Elixir and I'm trying to format a string to a PEM format. I have the certificate value like MIIDBTCCAe2...... and ...
New
aadeshere1
I have a another noob question about loop. Since elixir is immutable, while loop is not directly possible. total = 10 while total != 0 ...
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
Patoshizzle
After calling mix ecto.create I get this error: 17:00:32.162 [error] GenServer #PID&lt;0.412.0&gt; terminating ** (Postgrex.Error) FATAL...
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

We're in Beta

About us Mission Statement