jjh42 / mock

Mocking library for Elixir language
MIT License
646 stars 81 forks source link

Mock is crashing process in umbella project #143

Closed Fl4m3Ph03n1x closed 8 months ago

Fl4m3Ph03n1x commented 8 months ago

Background

I have an umbrella project, where I run mix test from the root. In one of the apps, I am mocking the File module using this library.

Problem

The issue here is that when I run mix test the process dies, with no error message to show:

Manager.Impl.Store.ReaderTest [test/unit/store/reader_test.exs]
  * test list_syndicates/1 returns the list of all known syndicates [L#496]** (EXIT from #PID<0.98.0>) killed

Code

The code of the test is as follows:

defmodule Manager.Impl.Store.ReaderTest do
  use ExUnit.Case, async: false

  alias Manager.Impl.Store.Reader

  import Mock

  setup do
    %{
      file_io: File,
      paths: [syndicates: ["syndicates.json"]]
    }
  end

  describe "lists syndicates" do
    test_with_mock "returns the list of all known syndicates", %{paths: paths} = deps, File, [],
      read: fn _filename -> {:ok, "[\"utc\"]"} end do
      # Act
      actual = Reader.list_syndicates(deps)

      expected = {:ok, [%Syndicate{name: "UTC", id: :utc, catalog: []}]}

      expected_path = Path.join(paths[:syndicates])

      # Assert
      assert actual == expected
      assert_called(File.read(expected_path))
    end
  end
end

In comparison, the following test (which does not use mock) works just fine:

defmodule Manager.Impl.Store.ReaderTest do
  @moduledoc false

  use ExUnit.Case, async: false

  alias Manager.Impl.Store.Reader

  import Mock

  setup do
    %{
      paths: [syndicates: ["syndicates.json"]]
    }
  end

  describe "list_syndicates/1" do
    defmodule FileMockListSyndicates do
      @moduledoc false

      def read(path) do
        assert path == "syndicates.json"
        {:ok, "[\"utc\"]"}
      end
    end

    setup do
      %{
        file_io: Manager.Impl.Store.ReaderTest.FileMockListSyndicates
      }
    end

    test "returns the list of all known syndicates",
         %{paths: paths} = deps do
      # Act
      actual = FileSystem.list_syndicates(deps)
      expected = {:ok, [%Syndicate{name: "UTC", id: :utc, catalog: []}]}

      # Assert
      assert actual == expected
    end
  end
end

To me this is rather surprising. One alternative crashes the process with no error message, while the other makes everything work.

To me, this indicates one of three problems:

  1. A problem with the library
  2. A problem with my setup of the library
  3. A problem with the test that causes the process to crash

Without any information about the error, I can't be sure. However I believe the tests to be simple enough that excluding options 2 and 3 does not seem outlandish.

Question

Why is my process dying, and how can I fix it?

Fl4m3Ph03n1x commented 8 months ago

I now believe this is an issue with :meck https://elixirforum.com/t/mock-is-crashing-process-in-umbella-project/61017/9?u=fl4m3ph03n1x

So I am choosing to close this issue.