phpspec / prophecy

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

How can I return a new instance each time a method is invoked #570

Closed a-ayala closed 1 year ago

a-ayala commented 1 year ago

I am mocking a method which returns a new instance of a class. However using willReturn will of course return the instance I pass it.

For example:

$prophecy->method()->willReturn( new \DateTime() );

I would to be able to create a new instance whenever the method is invoked as I cannot guarantee how many times it will be called.

So far I've done this using a CallbackPromise. Just wondering if there's another way, or if this is the intended way?

$prophecy->method()->willReturn( new CallbackPromise( function () { new \DateTime() } ) )
stof commented 1 year ago

passing a CallbackPromise won't work, as that would actually return that CallbackPromise (willReturn takes the returned value as argument, not a promise).

You should use the will() method instead. And the nice thing here is that this method accepts either a PromiseInterface or a callback (callbacks are automatically converted to a CallbackPromise). So the simple solution looks like that:

$prophecy->method()->will(function () { return new \DateTime(); });

// or even shorter with short lambdas:
$prophecy->method()->will(fn () => new \DateTime());
a-ayala commented 1 year ago

amazing, thank you @stof