From e59eb349029253f4931526c7fd57cdae9b8ca128 Mon Sep 17 00:00:00 2001 From: Keith Salisbury Date: Wed, 29 Jan 2020 21:44:09 +0000 Subject: [PATCH] Mix test --no-start By preventing the application tree starting automatically we're able to start the worker as we need, however this does mean each test will need to start the processes it needs. This could be a contenious issue. One downside of this approach is that we're now forced to set Mox into "global" mode because we don't have a pid to pass to `Mox.allow/2` and we need to call `Mox.expect/2` before calling `Worker.start_link/0` AND we need the newly created `Worker` process to be able to "see" the mocked `foo/0` function. Basically it's a chicken and egg situation. --- mix.exs | 7 +++++++ test/test_helper.exs | 12 ++++++++++++ test/worker_test.exs | 23 ++++++----------------- 3 files changed, 25 insertions(+), 17 deletions(-) diff --git a/mix.exs b/mix.exs index b9dd69a..4ecc263 100644 --- a/mix.exs +++ b/mix.exs @@ -8,6 +8,7 @@ defmodule Example.MixProject do elixir: "~> 1.9", elixirc_paths: elixirc_paths(Mix.env()), start_permanent: Mix.env() == :prod, + aliases: aliases(), deps: deps() ] end @@ -32,4 +33,10 @@ defmodule Example.MixProject do {:mox, "~> 0.5.1", only: :test} ] end + + def aliases do + [ + test: "test --no-start" + ] + end end diff --git a/test/test_helper.exs b/test/test_helper.exs index 869559e..1fd4b23 100644 --- a/test/test_helper.exs +++ b/test/test_helper.exs @@ -1 +1,13 @@ +# In order to use Mox.Server we need to ensure all applications for +# dependencies are loaded, and to call `Appplication.spec/2` requires that +# the application has been loaded +import Application + +load(:example) +Enum.each(spec(:example, :applications), &ensure_all_started/1) + +# Define our mocks +Mox.defmock(Example.MockService, for: Example.ServiceBehaviour) + +# Start the test framework ExUnit.start() diff --git a/test/worker_test.exs b/test/worker_test.exs index b734bfd..636d7b9 100644 --- a/test/worker_test.exs +++ b/test/worker_test.exs @@ -3,29 +3,18 @@ defmodule Example.WorkerTest do import Mox alias Example.Worker - describe "default service" do - test "returns default service foo" do - assert Worker.get_foo() =~ ~s(default says foo) - end - end + setup :verify_on_exit! describe "mocked service" do - setup do - # Normally you would add this to `test_helper.ex`, or `support/mocks.ex - Mox.defmock(Example.MockService, for: Example.ServiceBehaviour) - - Example.MockService - |> expect(:foo, fn -> "setup all says foo" end) - - :ok - end - - setup :verify_on_exit! + # We have to set Mox to global because we would have an impossible chicken + # and egg situation wtih Mox.allow/2 and Worker.start_link/0 + setup :set_mox_global test "returns mocked service foo" do Example.MockService |> expect(:foo, fn -> "mock says foo" end) - |> allow(self(), Process.whereis(Worker)) + + Worker.start_link() assert Worker.get_foo() =~ ~s(mock says foo) end