Skip to content

restore/1 exposes restoration as complete before it may actually be complete #85

Description

@liamwhite

The implementation of restore/1 calls the server:

@doc """
Restores a module to its original state.
"""
@spec restore(module :: module()) :: :ok
def restore(module) do
call(module, :restore, fn -> :ok end)
end

which triggers the mock server to shutdown:

def handle_call(:restore, _from, state) do
{:stop, {:shutdown, {:restore, do_restore(state)}}, :ok, state}
end

@spec call(module :: module(), message :: term(), default :: term()) :: term()
defp call(module, message, default) do
server = Naming.server(module)
try do
Freezer.get(GenServer).call(server, message)
catch
:exit, {:noproc, _} ->
default.()
end
end

GenServer will then reply to the call while termination is in progress.

If you do something silly in your test like

  def reset_spy do
    restore(MyModule)
    spy(MyModule)
  end

, this will almost guarantee a test flake when spy/1 sees the old pid that is in the process of terminating, and then not create a new Mock server. So the new spy will not work.

The proper fix for this would be to make sure restore waits until the mock server is fully terminated.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions