Weave 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

Mockery Module Laravel Package

codeception/mockery-module

Codeception module that integrates the Mockery mocking framework into your test suite, making it easy to create, use, and verify mock objects in PHP unit and functional tests with minimal setup.

View on GitHub
Deep Wiki
Context7

Getting Started

  1. Install the module and Mockery in the suite that needs it:

    composer require --dev codeception/mockery-module mockery/mockery
    
  2. Enable it in the suite config, usually unit.suite.yml or a dedicated integration.suite.yml:

    modules:
        enabled:
            - Asserts
            - Mockery
    

    If the short name is not resolved, use the fully qualified class name shown by composer show codeception/mockery-module or vendor/codeception/mockery-module/src.

  3. Rebuild the actor classes and check which methods are now available on $I:

    vendor/bin/codecept build
    
  4. First use case: a Cest test that needs a collaborator replaced:

    public function rejectsUnknownUser(UnitTester $I): void
    {
        $repository = $I->makeEmpty(UserRepository::class);
        $repository->shouldReceive('findByEmail')
            ->once()
            ->with('[email protected]')
            ->andReturn(null);
    
        $service = new RegisterUser($repository);
    
        $I->expectException(UserNotFoundException::class, function () use ($service) {
            $service->execute('[email protected]');
        });
    }
    

Where to look first:

  • The package README and the module class under vendor/codeception/mockery-module/.
  • The module’s own tests/examples, which show the exact helper names supported by the installed version.
  • Codeception\Util\Stub and Codeception\Test\Unit docs. If you are already writing Codeception\Test\Unit tests, Mockery integration is largely built in; this module is most useful for Cest/Cept-style tests or for centralizing Mockery lifecycle handling.
  • composer.json / composer.lock to confirm the Mockery version and PHP constraints, since the module’s last release was in 2022.

The core day-to-day value is not a large API: it is automatic Mockery::close() cleanup after each test, so expectations are verified and global Mockery state does not leak between Cest tests. Even if you create mocks with Mockery::mock() directly, enabling the module gives you that lifecycle behavior.

Implementation Patterns

Use the module as the Mockery lifecycle owner. Put it in every suite where tests call Mockery::mock(), Mockery::spy(), Mockery::close(), or the module’s helper methods. Do not manually call Mockery::close() in each Cest method; let the module’s _after hook handle it.

Prefer the module’s actor helpers for common cases. Depending on the installed version, the actor typically exposes helpers mirroring Mockery/Stub creation, such as:

$stub    = $I->make(SomeClass::class, ['getName' => 'John']);
$strict  = $I->makeEmpty(SomeClass::class);
$partial = $I->makePartial(SomeClass::class);

Use makeEmpty() when every interaction must be explicit, make() when you want default return values for unstubbed methods, and partial mocks when you need real behavior on most methods but want to override one or two. Verify the exact helper set in the module class before building abstractions around it.

Interaction testing pattern. Create the mock, declare expectations, inject it into the system under test, execute, and let teardown verify:

public function sendsWelcomeEmail(UnitTester $I): void
{
    $mailer = $I->makeEmpty(Mailer::class);
    $mailer->shouldReceive('send')
        ->once()
        ->with(Mockery::on(fn ($message) => $message->to === '[email protected]'));

    (new RegisterUser($mailer))->execute('[email protected]');
}

Because verification happens during _after, a forgotten or extra call fails at teardown. For critical interactions, consider adding an explicit assertion via Mockery::getContainer()->mockery_getExpectationCount() or by calling the real method and asserting observable output as well.

Spy pattern for legacy code. When it is easier to exercise real code and inspect calls afterward, create a spy or partial mock, pass it through the real flow, then assert received calls before the end of the test. Spies are useful when refactoring toward explicit dependency injection.

Constructor and dependency-injection patterns. For services with constructor dependencies, create mocks in the test and pass them directly:

$logger = $I->makeEmpty(Logger::class);
$service = new OrderService($logger);

For container-based applications, combine this module with the framework module you already use (for example Laravel’s module) and be deliberate about which mock() helper you are calling. In Laravel-oriented suites, the framework module may provide its own container-aware mock methods; use those for facades/container bindings and this module for plain Mockery collaborators.

Reusable fixture methods in Cest. Keep mock creation inside small helper methods on the Cest class to avoid a 15-line arrange block in every test:

private function makeUserRepository(UnitTester $I): UserRepository
{
    $repo = $I->makeEmpty(UserRepository::class);
    $repo->shouldReceive('save')->once();
    return $repo;
}

Data providers. Create mocks inside the test method or a _before hook, not in the data provider itself. Providers run before the test lifecycle; mocks created there may be closed or reset before the test body runs.

Custom module extension. If you need project-wide Mockery configuration, create a small module that extends the package module and sets configuration in _before:

protected function _before(TestInterface $test): void
{
    parent::_before($test);
    Mockery::getConfiguration()->allowMockingNonExistentMethods(false);
}

This centralizes strict Mockery settings instead of repeating them in every Cest class.

Do not use this as an integration-test database substitute. Mockery is for seams and collaborator interactions. For persistence behavior, use the appropriate Db/Doctrine module or a real test database; mocks of repositories in an integration test often hide the bugs you are trying to catch.

Gotchas and Tips

Expectation failures surface at teardown. Since the module closes Mockery after the test, a shouldReceive()->once() that was never called fails in _after, not at the line where you expected it. If the failure location is confusing, add shouldHaveReceived checks or call the interaction explicitly and assert an observable result. This is the most common debugging friction with any auto-closing Mockery integration.

Do not double-manage the lifecycle. If you call Mockery::close() manually and the module also closes in _after, you can get confusing behavior, especially if you inspect mocks after closing. Choose one owner.

Module name and method collisions. Codeception modules aggregate methods onto the actor. If your suite enables Laravel, Doctrine, or another module that exposes mock(), make(), or similar names, the last enabled module or Codeception’s resolution rules may surprise you. Check $I-> methods after codecept build and prefer explicit module access if needed:

$mockery = $this->getModule('Mockery');

codecept build is required after enabling the module. Changes to suite YAML do not regenerate actor classes automatically. A missing method on $I is usually a stale actor, not a missing package.

Mockery cannot mock everything. Final classes, final methods, private methods, and static methods are common failure points. For static/global calls, Mockery alias or overload mocks can work but are fragile and leak globally. Prefer refactoring to inject the dependency.

Partial mocks and constructors. Understand whether your helper calls the real constructor. makeEmpty() produces strict doubles; partial mocks may invoke real methods and constructors. If a class has a heavy constructor, pass constructor args explicitly or use a strict mock with expectations instead.

Configure Mockery strictly. Mockery’s default behavior can allow mocking non-existent methods, which hides typos in method names. In a base module or _before hook, set:

Mockery::getConfiguration()->allowMockingNonExistentMethods(false);

Be aware that this is process-global configuration and must be reset or consistently reapplied across tests.

Beware global state leaks. Mockery uses a global container. If a suite uses Mockery without the module, mocks can leak between tests. Enable the module in every suite that creates Mockery mocks directly, and avoid storing mocks in static properties.

Version and maintenance risk. The package’s last release is from 2022 and it has very low adoption. Check compatibility with your PHP and Mockery versions, especially on PHP 8.2+. If Composer blocks installation because of Mockery constraints, you may need to constrain Mockery yourself or use a small local module instead. The core behavior is small enough that a fallback is straightforward:

class MockeryLifecycle extends \Codeception\Module
{
    public function _after(\Codeception\TestInterface $test): void
    {
        \Mockery::close();
    }
}

Parallel test runs. Mockery state is per PHP process, so parallel Codeception runs are generally fine as long as each worker executes the module’s _after hook. Do not share mock objects between processes or rely on static mocks across test boundaries.

Coverage noise. Generated mock/proxy classes can appear in coverage reports or increase uncovered-line counts. Exclude generated Mockery classes or focus coverage on production code; do not let a mocked collaborator’s generated code drive coverage thresholds.

Debugging techniques. Use Mockery::getContainer()->mockery_getExpectationCount() to inspect expectation counts while debugging. Run the single failing Cest with --debug to see module hooks and teardown order. When an expectation is not matching, simplify the with() matcher and use Mockery::on() with a temporary var_dump() to inspect the actual argument.

Extension points are the hooks. The module’s useful extension surface is _before and _after: set Mockery global configuration before each test, close mocks after each test, and optionally assert extra invariants. For framework integration, Mockery::setContainer() can wire Mockery into an application container, but do this deliberately and reset it in teardown.

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.
novasa/laravel-language-center
opencage/geocode
adolfoholzer/parameters
livenetworks/ln-starter
shitoudev/permissionmanager
johannesclimacus/laravel-tui
hocvt/seotools
vitalybaev/sypexgeo
amphibee/themosis-ignition
gito-me/fast-excel
frankyso/laravel-ipaymu
geolize-studio/laravel-chile
boomerangui/chat
jinas/dhivatar
store-doc/laravel-storage-driver
plus-it/laravel-translation-manager
diephp/perhaps
diephp/telegraph
osmaviation/spreadsheet
microsoft/fluentui-system-icons