-
Notifications
You must be signed in to change notification settings - Fork 242
Description
prophecy-phpunit does not allow creating doubles in data provider because those must be static while prophesize is an instance method. Being an instance method is necessary because mocks must be associated to a test so that their predictions are verified at the end of the test.
Comparing this to PHPUnit mock objects, they have 2 different APIs. The method createMock is an instance method (for the same reason that our method) but createStub is static.
I suggest introducing 3 modes of operations for the ObjectProphecy:
- stub mode:
MethodProphecy::shouldandMethodProphecy::shouldHavethrow an exception as defining or verifying predictions on a stub is forbidden. Object prophecies created in stub mode are not registered in theProphet::$propheciesproperty. Unexpected calls to a stub throw immediately (see RFC: New unexpected method call behaviour #528 for justification, see [DX] Mocks should fail immediately #508 and Callcenter returns null on non registered method call #472 as well). The existing special dummy-like behavior allowing any method call when there is no expectation will be gone (maybe only deprecated at first as discussed in RFC: New unexpected method call behaviour #528, to be checked). As an optimization, we could even makeObjectProphecy::findProphecyMethodCallsthrow for stubs (it is used only for checking predictions) which then allows the CallCenter to skip registering all calls in itsrecordedCallsproperty. - mock mode:
MethodProphecy::shouldHavethrows an exception. Unexpected calls to a mock throw immediately (see RFC: New unexpected method call behaviour #528, solves [DX] Mocks should fail immediately #508) - spy mode: the existing mode where unexpected calls are reported when verifying predictions at the end of the test
Maybe the mock and spy modes can be combined into a single mode based on the suggestion done in #528:
- unexpected method calls for void-returning methods are reported when verifying predictions
- other unexpected methods calls are reported immediately
- spying on a method that is not returning void (this includes methods that have no return type) involves allowing the call by using one of the
willmethod to define the behavior of the method (solving the case that it currently returnsnulleven though the phpdoc makes that an unexpected type)
This combined approach has a DX drawback for projects that don't rely on spies at all: reporting unexpected method calls immediately makes it a lot easier to debug the issue, because the unexpected call itself (and its call stack) is part of the stack trace of the UnexpectedCallException. On the other hand, it allows to keep our API simple, by having prophesize return full-featured object prophecies as done today (while stricter based on #528) and prophesizeStub returning a stub ObjectProphecy.