phpspec / prophecy

Highly opinionated mocking framework for PHP 5.3+
MIT License
8.53k stars 242 forks source link

Can't mock class with a final constructor #295

Open Taluu opened 8 years ago

Taluu commented 8 years ago

It's related to #54, but I though opening a new issue would be better. So here goes ;

I have a class that have a final construct (so that the stuff in it doesn't get overwritten), but I need to use (inject) said class into the class I need to test. I am using a prophecy mock here, because I need to just invoke one specific method in one test case (which I would like to mock), and in the other cases, just passing it as a stub.

But, when trying to "prophesize" this class, I have the following exception triggered : Prophecy\Exception\Doubler\MethodNotExtendableException: Method __construct is not extendable, so can not be added.

I am guessing this is a problem in the disableConstructorPatch, as this is one of the few places that tries to "automatically" add the method node for the __construct method, and trigger said exception. I know there was a fix made by @ciaranmcnulty (#59), but maybe was it not taken into account when realizing the disableConstructPatch ?

mikedfunk commented 7 years ago

I see no documentation on how to disable the constructor in a mock. How does one apply disableConstrutorPatch? I see the class definition but don't know how to apply a patch to a prophecy.

bitwombat commented 6 years ago

Replace the class with an interface and prophesize that.

mikedfunk commented 6 years ago

The problem is when vendor code does this and does not implement an interface or extend an abstract. In my case this was the couchbase php SDK. I had to wrap it with a decorator to get tests working until they eventually removed the final declarations from the offending class.

bitwombat commented 6 years ago

Huh... my problem was with the vendor class and its constructor declared final. My class extended it. So, I created an interface, made my class still extend the vendor class, but implement the interface, then made my code and phpspec rely on the interface...

Same thing?

samsonasik commented 5 years ago

should can be closed in favor of pr #427