From ada67ca8f17037c57cf38e4d1b338f3883ff768f Mon Sep 17 00:00:00 2001 From: Marcos Wright-Kuhns Date: Fri, 4 Aug 2023 11:51:11 -0700 Subject: [PATCH 1/3] Add failing "mocks are over-called" tests --- lib/mox/application.ex | 5 ++++- test/mox_test.exs | 39 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 43 insertions(+), 1 deletion(-) diff --git a/lib/mox/application.ex b/lib/mox/application.ex index cb7b52d..4039f23 100644 --- a/lib/mox/application.ex +++ b/lib/mox/application.ex @@ -4,7 +4,10 @@ defmodule Mox.Application do use Application def start(_, _) do - children = [Mox.Server] + children = [ + Mox.Server, + {Task.Supervisor, name: MoxTests.TaskSupervisor}, + ] Supervisor.start_link(children, name: Mox.Supervisor, strategy: :one_for_one) end end diff --git a/test/mox_test.exs b/test/mox_test.exs index 5743546..310e702 100644 --- a/test/mox_test.exs +++ b/test/mox_test.exs @@ -363,6 +363,24 @@ defmodule MoxTest do assert_raise Mox.VerificationError, message, &verify!/0 end + test "verifies when mocks are over-called in the process in private mode" do + set_mox_private() + + verify!() + expect(CalcMock, :add, 1, fn x, y -> x + y end) + + # Emulate mock calls within code that has aggressive error handling + try do + CalcMock.add(1, 2) + CalcMock.add(3, 4) + catch _, _ -> + :ok + end + + message = ~r"expected CalcMock.add/2 to be invoked once but it was invoked 2 times" + assert_raise Mox.VerificationError, message, &verify!/0 + end + test "verifies all mocks for the current process in global mode" do set_mox_global() @@ -385,6 +403,27 @@ defmodule MoxTest do message = ~r"expected CalcMock.add/2 to be invoked 2 times but it was invoked once" assert_raise Mox.VerificationError, message, &verify!/0 end + + test "verifies mocks are over-called for the current process in global mode" do + set_mox_global() + + verify!() + expect(CalcMock, :add, 1, fn x, y -> x + y end) + + message = ~r"expected CalcMock.add/2 to be invoked once but it was invoked 0 times" + assert_raise Mox.VerificationError, message, &verify!/0 + + task = + Task.Supervisor.async_nolink(MoxTests.TaskSupervisor, fn -> + CalcMock.add(2, 3) + CalcMock.add(4, 5) + end) + + Task.yield(task) + + message = ~r"expected CalcMock.add/2 to be invoked once but it was invoked 2 times" + assert_raise Mox.VerificationError, message, &verify!/0 + end end describe "verify!/1" do From 7b183f950380538b1109f6e7ad8e6777c04664dc Mon Sep 17 00:00:00 2001 From: Marcos Wright-Kuhns Date: Fri, 4 Aug 2023 12:31:54 -0700 Subject: [PATCH 2/3] Add failing "mocks over-called" verify!/1 tests --- test/mox_test.exs | 51 +++++++++++++++++++++++++++++++++++++------ test/support/mocks.ex | 1 + 2 files changed, 45 insertions(+), 7 deletions(-) diff --git a/test/mox_test.exs b/test/mox_test.exs index 310e702..abe03aa 100644 --- a/test/mox_test.exs +++ b/test/mox_test.exs @@ -413,13 +413,11 @@ defmodule MoxTest do message = ~r"expected CalcMock.add/2 to be invoked once but it was invoked 0 times" assert_raise Mox.VerificationError, message, &verify!/0 - task = - Task.Supervisor.async_nolink(MoxTests.TaskSupervisor, fn -> - CalcMock.add(2, 3) - CalcMock.add(4, 5) - end) - - Task.yield(task) + Task.Supervisor.async_nolink(MoxTests.TaskSupervisor, fn -> + CalcMock.add(2, 3) + CalcMock.add(4, 5) + end) + |> Task.yield() message = ~r"expected CalcMock.add/2 to be invoked once but it was invoked 2 times" assert_raise Mox.VerificationError, message, &verify!/0 @@ -444,6 +442,25 @@ defmodule MoxTest do assert_raise Mox.VerificationError, message, &verify!/0 end + test "verifies when mocks are over-called in the process in private mode" do + set_mox_private() + + verify!(CalcMock) + expect(CalcMock, :add, 1, fn x, y -> x + y end) + expect(SciCalcOnlyMock, :exponent, fn x, y -> x * y end) + + # Emulate mock calls within code that has aggressive error handling + try do + CalcMock.add(1, 2) + CalcMock.add(3, 4) + catch _, _ -> + :ok + end + + message = ~r"expected CalcMock.add/2 to be invoked once but it was invoked 2 times" + assert_raise Mox.VerificationError, message, fn -> verify!(CalcMock) end + end + test "verifies all mocks for current process in global mode" do set_mox_global() @@ -467,6 +484,26 @@ defmodule MoxTest do assert_raise Mox.VerificationError, message, &verify!/0 end + test "verifies mocks are over-called for the current process in global mode" do + set_mox_global() + + verify!() + expect(CalcMock, :add, 1, fn x, y -> x + y end) + expect(SciCalcOnlyMock, :exponent, fn x, y -> x * y end) + + message = ~r"expected CalcMock.add/2 to be invoked once but it was invoked 0 times" + assert_raise Mox.VerificationError, message, fn -> verify!(CalcMock) end + + Task.Supervisor.async_nolink(MoxTests.TaskSupervisor, fn -> + CalcMock.add(2, 3) + CalcMock.add(4, 5) + end) + |> Task.yield + + message = ~r"expected CalcMock.add/2 to be invoked once but it was invoked 2 times" + assert_raise Mox.VerificationError, message, fn -> verify!(CalcMock) end + end + test "raises if a non-mock is given" do assert_raise ArgumentError, ~r"could not load module Unknown", fn -> verify!(Unknown) diff --git a/test/support/mocks.ex b/test/support/mocks.ex index bd56b15..95a7bc8 100644 --- a/test/support/mocks.ex +++ b/test/support/mocks.ex @@ -1,4 +1,5 @@ Mox.defmock(CalcMock, for: Calculator) +Mox.defmock(SciCalcOnlyMock, for: ScientificCalculator) Mox.defmock(SciCalcMock, for: [Calculator, ScientificCalculator]) Mox.defmock(SciCalcMockWithoutOptional, From 31217186dc7b618ea35448d2175377408a574fb3 Mon Sep 17 00:00:00 2001 From: Marcos Wright-Kuhns Date: Mon, 7 Aug 2023 16:03:11 -0700 Subject: [PATCH 3/3] Use `start_supervised!` within tests ...instead of changing application.ex --- lib/mox/application.ex | 5 +---- test/mox_test.exs | 2 ++ 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/lib/mox/application.ex b/lib/mox/application.ex index 4039f23..cb7b52d 100644 --- a/lib/mox/application.ex +++ b/lib/mox/application.ex @@ -4,10 +4,7 @@ defmodule Mox.Application do use Application def start(_, _) do - children = [ - Mox.Server, - {Task.Supervisor, name: MoxTests.TaskSupervisor}, - ] + children = [Mox.Server] Supervisor.start_link(children, name: Mox.Supervisor, strategy: :one_for_one) end end diff --git a/test/mox_test.exs b/test/mox_test.exs index abe03aa..e7c1152 100644 --- a/test/mox_test.exs +++ b/test/mox_test.exs @@ -405,6 +405,7 @@ defmodule MoxTest do end test "verifies mocks are over-called for the current process in global mode" do + start_supervised!({Task.Supervisor, name: MoxTests.TaskSupervisor}) set_mox_global() verify!() @@ -485,6 +486,7 @@ defmodule MoxTest do end test "verifies mocks are over-called for the current process in global mode" do + start_supervised!({Task.Supervisor, name: MoxTests.TaskSupervisor}) set_mox_global() verify!()