Weave Code
Code Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Prophecy Laravel Package

phpspec/prophecy

Highly opinionated yet flexible PHP mocking framework for unit tests. Create test doubles with a Prophet, define expected calls and return values, then reveal mocks and verify predictions. Works with PHPUnit and other frameworks; requires PHP 7.2+.

View on GitHub
Deep Wiki
Context7

Getting Started

Start by installing phpspec/prophecy via Composer in your require-dev section:

composer require --dev phpspec/prophecy

Initialize a Prophet instance—typically in your test class setUp()—and use prophesize() to create object prophecies:

$prophet = new \Prophecy\Prophet;
$mock = $prophet->prophesize(SomeInterface::class);

Then reveal the double with reveal() and inject it into your SUT. Finally, call checkPredictions() (e.g., in tearDown()) to assert that expected calls occurred. This minimal workflow enables expressive, behavior-focused testing even with PHPUnit.

Implementation Patterns

  • Stubbing behavior: Define return values or side effects using method prophecies:

    $service->process(Argument::type(User::class))->willReturn(true);
    

    Use willReturn($v1, $v2, ...) for sequential calls with identical signatures.

  • Dynamic behavior via callbacks: Use will() with a closure to model state changes or interdependencies:

    $user->setName(Argument::type('string'))->will(function ($args) {
        $this->name = $args[0];
        return $this;
    });
    
  • Argument wildcards: Leverage Argument::type(), Argument::exact(), Argument::containingString(), etc., to avoid brittle exact-match assertions. Combine specificity (e.g., type()) and generality (any()) strategically—the more precise token wins in ambiguous matches.

  • ** mocks vs stubs**: Use shouldBeCalled() / shouldNotBeCalled() or custom predictions (e.g., times(2)) to assert interactions. Use shouldBeCalledOnce() or times() helpers for brevity. Always pair mocks with checkPredictions().

  • Reveal early, verify late: Reveal doubles early in the test for injection, but defer prediction checks to tearDown() or explicit assert() calls to ensure all interactions are captured.

Gotchas and Tips

  • Dummies vs stubs: Calling undefined methods on a stub throws UnexpectedCallException. For stubs, all public method calls must be prophesized. Dummies (from a prophecy without promises) allow any call and return null.

  • Idempotency of method prophecies: $mock->foo(1) returns the same MethodProphecy instance on repeated calls with identical arguments. Modifying it later (e.g., chaining shouldNotBeCalled()) affects all prior usages.

  • Argument token matching: Tokens are scored and the highest-score match wins. Using Argument::any() in multiple overlapping prophecies can silently override more precise ones—prefer precise tokens (type(), which()) and order carefully.

  • Custom predictions: Prophecy lacks built-in times() in phpspec/prophecy v1.x (despite docs); it’s only available via phpspec/prophecy extensions like phpspec/prophecy-phpunit. Consider installing phpspec/prophecy-phpunit or define custom predictions:

    $mock->foo()->shouldHaveBeenCalledTimes(2);
    
  • Revealed objects are proxies: The double’s reveal() result is a runtime-generated proxy class. Functions like get_class() or instanceof work, but debug_backtrace() may be misleading—avoid relying on internal class names.

  • Failing predictions don’t halt execution: Predictions are checked only on checkPredictions(); calls may proceed normally before verification. This avoids early-exit issues but means assertions only surface at test teardown.

  • Extensibility: Extend with custom TokenInterface or PromiseInterface/PredictionInterface implementations for domain-specific patterns (e.g., Argument::like($regex) or CallWithSideEffectPromise).

Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
davejamesmiller/laravel-breadcrumbs
artisanry/parsedown
christhompsontldr/phpsdk
enqueue/dsn
bunny/bunny
enqueue/test
enqueue/null
enqueue/amqp-tools
milesj/emojibase
bower-asset/punycode
bower-asset/inputmask
bower-asset/jquery
bower-asset/yii2-pjax
laravel/nova
spatie/laravel-mailcoach
spatie/laravel-superseeder
laravel/liferaft
nst/json-test-suite
danielmiessler/sec-lists
jackalope/jackalope-transport