elixir_mock icon indicating copy to clipboard operation
elixir_mock copied to clipboard

Pattern matching in stubbed functions does not record call args correctly

Open wanderanimrod opened this issue 8 years ago • 1 comments

Current behaviour

All within an exunit test context

with_mock(mock) = defmock_of RealModule do
  def is_age_one?(%{age: 1}) do
     {:ok, "age is one"}
  end

  def is_age_one?(%{age: age}) do
    {:error, "age is not one. it is #{age}"}
  end
end

response = mock.is_age_one? %{age: 1, height: 1.74}
assert response == {:ok, "age is one"} #should pass

assert_called mock.is_age_one?(%{age: 1, height: 1.74})
# this fails, only recording the section of the arg in the 
# function's pattern match which is: %{age: 1}

This could also imply that pattern matching with functions in mock definitions does not work correctly, particularly with maps, and possibly with other data structures.

wanderanimrod avatar Jun 18 '17 00:06 wanderanimrod

Stumbled into a workaround for this bug. When defining functions that take maps as arguments within mocks, assign the whole map to a variable.

with_mock(mock) = defmock_of RealModule do
  def is_age_one?(%{age: 1} = _dummy_var) do
     {:ok, "age is one"}
  end
  
  # instead of
  def is_age_one?(%{age: 1}) do
     {:ok, "age is one"}
  end
end

For some reason, this fixes it. Will investigate more if this workaround doesn't work for you.

wanderanimrod avatar Apr 11 '18 00:04 wanderanimrod