|
| 1 | +--- |
| 2 | +outline: [2, 3] |
| 3 | +llms: true |
| 4 | +llms_description: "Integration with Mockery mocking library: installation, setup at application and suite levels, automatic mock expectation verification after each test, status mapping (Passed, Risky, Failed)." |
| 5 | +--- |
| 6 | + |
| 7 | +# Mockery |
| 8 | + |
| 9 | +[Mockery](https://github.com/mockery/mockery) is a popular PHP mocking library with an expressive API (`Mockery::mock()`, `expects()`, `spy()`). The `testo/bridge-mockery` package integrates it with Testo. |
| 10 | + |
| 11 | +<plugin-info name="Mockery" class="\Testo\Bridge\Mockery\MockeryPlugin" /> |
| 12 | + |
| 13 | +## Installation |
| 14 | + |
| 15 | +```bash |
| 16 | +composer require --dev mockery/mockery testo/bridge-mockery |
| 17 | +``` |
| 18 | + |
| 19 | +## Setup |
| 20 | + |
| 21 | +Register the <class>\Testo\Bridge\Mockery\MockeryPlugin</class> in the `plugins` section — either at the application level (for all suites) or for a specific Test Suite (for a particular set of tests). |
| 22 | + |
| 23 | +::: code-group |
| 24 | +```php [Application level] |
| 25 | +use Testo\Application\Config\ApplicationConfig; |
| 26 | +use Testo\Bridge\Mockery\MockeryPlugin; |
| 27 | + |
| 28 | +return new ApplicationConfig( |
| 29 | + src: ['src'], |
| 30 | + suites: [ /** Suites **/ ], |
| 31 | + plugins: [ |
| 32 | + new MockeryPlugin(), |
| 33 | + ], |
| 34 | +); |
| 35 | +``` |
| 36 | + |
| 37 | +```php [Suite level] |
| 38 | +use Testo\Application\Config\SuiteConfig; |
| 39 | +use Testo\Bridge\Mockery\MockeryPlugin; |
| 40 | + |
| 41 | +new SuiteConfig( |
| 42 | + name: 'Unit', |
| 43 | + location: ['tests/Unit'], |
| 44 | + plugins: [ |
| 45 | + new MockeryPlugin(), |
| 46 | + ], |
| 47 | +); |
| 48 | +``` |
| 49 | +::: |
| 50 | + |
| 51 | +## Mock Expectation Verification |
| 52 | + |
| 53 | +The bridge automatically verifies mock expectations after each test and maps the result to Testo statuses — manual teardown is not required. The rule is straightforward: **if you declare an expectation and fulfill it, the test passes; if you don't, it fails.** |
| 54 | + |
| 55 | +- **A fulfilled expectation** counts as an assertion. So a test whose only check is a mock stays <enum>\Testo\Core\Value\Status::Passed</enum> rather than <enum>\Testo\Core\Value\Status::Risky</enum> (Testo marks a passing test with no assertions as risky — a safeguard against forgotten assertions, see <plugin>Assert</plugin>). |
| 56 | +- **An unfulfilled expectation** fails the test (**Failed**) and shows up in the assertion history as a failure. |
| 57 | + |
| 58 | +::: code-group |
| 59 | +```php [Passed] |
| 60 | +#[Test] |
| 61 | +public function notifies(): void |
| 62 | +{ |
| 63 | + $mailer = Mockery::mock(Mailer::class); |
| 64 | + $mailer->expects('send')->once(); // expectation — and an assertion at that |
| 65 | + |
| 66 | + (new Notifier($mailer))->notify('hi'); // send() is called once, fulfilling the expectation |
| 67 | +} |
| 68 | +``` |
| 69 | + |
| 70 | +```php [Risky] |
| 71 | +#[Test] |
| 72 | +public function notifies(): void |
| 73 | +{ |
| 74 | + $mailer = Mockery::spy(Mailer::class); |
| 75 | + |
| 76 | + (new Notifier($mailer))->notify('hi'); |
| 77 | + // no expectations, no assertions — nothing to check → Risky |
| 78 | +} |
| 79 | +``` |
| 80 | + |
| 81 | +```php [Failed] |
| 82 | +#[Test] |
| 83 | +public function notifies(): void |
| 84 | +{ |
| 85 | + $mailer = Mockery::mock(Mailer::class); |
| 86 | + $mailer->expects('send')->once(); // expect exactly one send() call |
| 87 | + |
| 88 | + // …but notify() was never called → expectation unfulfilled → Failed |
| 89 | +} |
| 90 | +``` |
| 91 | +::: |
| 92 | + |
| 93 | +::: info |
| 94 | +The plugin only works with regular tests (for example, those marked with the <attr>\Testo\Test</attr> attribute). In inline tests, benchmarks, and other test types, mocks are not verified or cleaned up automatically — you'll need to handle that yourself, directly through Mockery. |
| 95 | +::: |
0 commit comments