Closed jimmyharris closed 9 years ago
You can use a matcher to match against your object. You'll probably have to create your own custom matcher for this though. Actually, I think the latest master branch already does not perform a deepcopy for spies/stubs. Have you tried with the latest master?
I am running on the latest master. The issue isn't that it deep copies spies and stubs, but that it actually deep copies the table I am trying to compare against. I would effectively have to make an object instance ID that could be copied so that I could compare those item ID values to see if it is the same object. I wish there was some way to tell the stub/spy that I am spying on a member function so don't deep copy the first argument. something like:
spy.on.member( object, 'member' )
-- or
stub.member( object, 'methodName' )
Then we could call a utils.match_member_args( ... )
or something to take into account the 'self' operator.
Sorry, I was thinking that MyObject
was also a spy/stub. What about something like this?
spy.on(object, 'member').no_deepcopy_arg(1)
-- or
stub(object, 'member').no_deepcopy_arg(1)
This is a relatively easy change to make and it provides a general solution to prevent any arbitrary argument from being deep copied by the spy/stub. And you can always undo the operation with something like (in case you change your mind later):
s.deep_copy_arg(1) -- where s is a stub or spy
Actually, maybe a better interface would be something like
local match = require 'luassert.match'
assert.stub(s).was.called_with(match.is_ref(object))
Then you could also do
stub(object, 'member').on_call_with(match.is_ref(object))
I think this would be more flexible and intuitive to use.
I'll try to get a pull request sometime today or tomorrow.
@jimmyharris I submitted PR #124, which should resolve this. Can you give it a try and let me know what you think? It uses match.is_ref
to match against the object reference.
That sounds good actually.
That is actually a perfect solution.
I think the easiest way to explain this is with an example:
Let us assume I have the following object.
Now we add a method to
MyObject
that will first make a call to the stub, then change the value of the 'name' field.Later in a test we stub out
mock_method
and attempt to assert that it was called on the table referenced byMyObject
.The assertion will fail because the call history made a deep copy of MyObject when MyObject was in a different state.
I don't really have any ideas how to work around this. I feel like in every other case I would absolutely want the state to be copied for deep comparison.
I could always just say "I don't care" about the first argument but that solution feels unsatisfactory. Do you have any ideas on how I could go about dealing with this case?