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.
The implementation of
restore/1calls the server:patch/lib/patch/mock/server.ex
Lines 119 to 125 in 69e1a36
which triggers the mock server to shutdown:
patch/lib/patch/mock/server.ex
Lines 185 to 187 in 69e1a36
patch/lib/patch/mock/server.ex
Lines 207 to 217 in 69e1a36
GenServer will then reply to the call while termination is in progress.
If you do something silly in your test like
, this will almost guarantee a test flake when
spy/1sees 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.