Skip to content

feat(bridge): add Mockery bridge (testo/bridge-mockery)#254

Merged
roxblnfk merged 4 commits into
php-testo:1.xfrom
rossaddison:feature/bridge-mockery
Jul 3, 2026
Merged

feat(bridge): add Mockery bridge (testo/bridge-mockery)#254
roxblnfk merged 4 commits into
php-testo:1.xfrom
rossaddison:feature/bridge-mockery

Conversation

@rossaddison

Copy link
Copy Markdown
Contributor

Closes #41

What this adds

A new bridge/mockery/ package (testo/bridge-mockery) that integrates Mockery into Testo.

How it works

MockeryPlugin registers MockeryInterceptor as a TestRunInterceptor. The interceptor wraps every test in a try/finally and calls Mockery::close() after each one — whether it passed or failed. This ensures:

  • Unfulfilled mock expectations are reported as test failures.
  • The Mockery container is cleared between tests, preventing state leaking from one test into the next.

Usage

// testo.php
return new ApplicationConfig(
    plugins: [new \Testo\Bridge\Mockery\MockeryPlugin()],
    suites:  [new SuiteConfig(name: 'Unit', location: ['tests/Unit'])],
);
#[Test]
final class MyServiceTest
{
    public function callsRepository(): void
    {
        $repo = \Mockery::mock(UserRepository::class);
        $repo->expects('find')->with(1)->andReturn(new User(1));

        $service = new UserService($repo);
        $service->getUser(1);
        // Mockery::close() is called automatically — expectation is verified here
    }
}

Files

File Purpose
bridge/mockery/composer.json Package definition (testo/bridge-mockery)
bridge/mockery/src/MockeryPlugin.php PluginConfigurator — entry point users register
bridge/mockery/src/Internal/MockeryInterceptor.php TestRunInterceptor — calls Mockery::close() in finally
bridge/mockery/tests/Acceptance/MockeryBridgeTest.php Acceptance tests: mock, spy, container isolation

The bridge follows the same structure and conventions as the existing bridge/symfony-console and plugin/lifecycle packages.

Closes php-testo#41

Implements MockeryPlugin + MockeryInterceptor to call Mockery::close()
in a try/finally after every test, ensuring mock expectations are always
verified and the Mockery container is cleared between tests.
@rossaddison rossaddison requested a review from a team as a code owner July 2, 2026 22:17
@roxblnfk roxblnfk requested a review from Copilot July 3, 2026 07:46

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds a new testo/bridge-mockery package that integrates Mockery into Testo by registering a TestRunInterceptor intended to call Mockery::close() after each test, plus initial acceptance tests and root composer wiring.

Changes:

  • Add testo/bridge-mockery to the monorepo (package composer.json, plugin, interceptor, changelog).
  • Wire the new bridge into the root repo dev dependencies / suggestions and test autoloading.
  • Add initial acceptance tests and a dedicated suites definition for the bridge.

Reviewed changes

Copilot reviewed 7 out of 7 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
composer.json Adds the bridge as a dev dependency + suggestion, and adds test autoload mapping.
bridge/mockery/composer.json Defines the new testo/bridge-mockery package and its dependencies.
bridge/mockery/src/MockeryPlugin.php Plugin entry point registering the interceptor into the pipeline.
bridge/mockery/src/Internal/MockeryInterceptor.php Interceptor intended to ensure Mockery::close() runs after each test.
bridge/mockery/tests/suites.php Declares the acceptance test suite for the bridge package.
bridge/mockery/tests/Acceptance/MockeryBridgeTest.php Acceptance tests demonstrating mock/spy usage and intended teardown behavior.
bridge/mockery/CHANGELOG.md Adds initial changelog for version 0.1.0.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread bridge/mockery/src/Internal/MockeryInterceptor.php
Comment thread bridge/mockery/tests/suites.php
Comment thread bridge/mockery/tests/Acceptance/MockeryBridgeTest.php Outdated
@roxblnfk roxblnfk self-requested a review July 3, 2026 08:11
roxblnfk and others added 3 commits July 3, 2026 12:42
…ests

- register the package in release-please (config, version.json seed, split-publish tag)
- add mirror README and close-prs workflow to match the other bridges
- reduce CHANGELOG to a stub so release-please manages it
- wire the acceptance suite into testo.php and register MockeryPlugin on it
- strengthen the acceptance test: #[Covers] + assert the container is reset,
  and drop the risky spy test by adding a real assertion
- align the composer `suggest` wording with the infection entry

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
… as assertions

- MockeryInterceptor records verified expectations (ExpectationFulfilled) and unmet
  ones (ExpectationFailed) on the current test, so a mock-only test is not Risky and
  an unmet expectation fails the test instead of aborting the pipeline
- guard the process-global Mockery container across fiber suspensions with the same
  save/reset/restore dance as MessengerHub::scope
- tune ExpectationsInterceptor order to ORDER_ASSERTIONS + 2000 so the Assert plugin
  reads the history after the bridge records into it
- add Self / Feature / Stub tests covering mock+assert combinations and statuses
- declare testo/assert, testo/codecov, testo/test as dev dependencies

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Cover the failure path of the teardown: a stub that leaves an unmet expectation
(Failed) is followed by one that checks the container is empty at its start
(Passed). The latter only passes if close() cleared the container despite the
failure — proving the interceptor both fails the right test and resets state for
subsequent tests, not only when a test passes.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@codecov

codecov Bot commented Jul 3, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 0% with 1 line in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
bridge/mockery/src/MockeryPlugin.php 0.00% 1 Missing ⚠️

📢 Thoughts on this report? Let us know!

@roxblnfk roxblnfk merged commit 6f4596e into php-testo:1.x Jul 3, 2026
12 of 14 checks passed
@roxblnfk roxblnfk mentioned this pull request Jul 3, 2026
@roxblnfk

roxblnfk commented Jul 3, 2026

Copy link
Copy Markdown
Member

The docs is there https://php-testo.github.io/docs/bridge/mockery
Thanks

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Mockery

3 participants