Open elvetemedve opened 4 years ago
What's the point of cloning a double?
I guess the SUT does the doubling?
@ciaranmcnulty if it is as you guess, is pretty much useless to clone the double as the internal one (the SUT one) would be a totally different instance.
Well, as DateTime is a value object, your example would be much cleaner by not using a double at all, but using an actual DateTime object.
The issue you have here is that cloning the double still creates a double linked to the same ObjectProphecy, and so they don't have independent states.
I guess the SUT does the doubling?
@ciaranmcnulty Yes, that's the case.
Well, as DateTime is a value object, your example would be much cleaner by not using a double at all, but using an actual DateTime object.
@stof That's true, but I picked DateTime
as an example. I run into this problem on a project where the SUT is not a value object.
The issue you have here is that cloning the double still creates a double linked to the same ObjectProphecy, and so they don't have independent states.
That's happening exactly. Unfortunately deep cloning is not supported by PHP out of the box, so I can't fix it that way. Introducing a factory method could be a workaround.
@elvetemedve if we were cloning the ObjectProphecy when cloning the method, this might solve some things, but it might introduce other issues.
I think that cloning the ObjectProphecy (no matter if shallow or deep clone) has no value. If it is cloned in SUT code, what is executed inside the SUT is a code that hits a totally different double from test one. So, what's the point here? We already can't make assumption (stub methods, expectations) in test. Am I missing something?
Looking at it more in details, it seems very hard to implement __clone
in a way cloning the double while maintaining consistent state of the double and its associated ObjectProphecy and LazyDouble (inside the ObjectProphecy) due to being a circular object graph.
And expectations cannot work either as the Prophet class won't know about the cloned prophecy.
@ciaranmcnulty should we generate a __clone
method in doubles throwing an exception saying that cloning a Prophecy double is not supported, for easier debugging of why things don't work ?
And expectations cannot work either as the Prophet class won't know about the cloned prophecy.
Exactly. So I'm in favor of this
we generate a __clone method in doubles throwing an exception saying that cloning a Prophecy double is not supported, for easier debugging of why things don't work
When a Double object is cloned, the attached promises won't be cloned. Therefore the two objects are stitched together.
The example below demonstrates the problem.
Actual Output
Expected Output
Environment
Prophecy version: 1.11.1 PHP version: 7.4.9