MethodCall is used to represent a method call made on a double. It
stores the object the call was made on, the name of the method, any
arguments or block sent to the method, and the double itself. There were
quite a few places where we were using an (args, block) or (object,
args, block) tuple. We also already had a MethodCall class, and
additionally a MethodCallWithName class, and the two were basically the
same. These usages have all been collapsed.
The provided RSpec example looks a bit contrived, but it corresponds to
this perfectly reasonable Minitest test case that was not working:
class UserControllerTest < ActionController::TestCase
should permit(:name).for(:create)
should_not permit(:admin).for(:create)
end
This instantiates two matchers at class load time, which resulted in the
second one overriding the double collection of the first one. Then when
the tests are executed, the first matcher would fail, because its double
is not listening to ActionController::Parameters#permit -- only the
second matcher's double collection gets activated.
This is fixed in Doublespeak by only creating one double collection per
class.
This provides a robust solution for temporarily stubbing (and
unstubbing) methods. It will be internally by the strong parameters and
delegation matchers.