UnderstudyPHPUnitIntegration
Rasuvaeff\Understudy\PhpUnit\UnderstudyPHPUnitIntegration
Trait — Package: rasuvaeff/understudy-phpunit — Source — Version: v1.0.0
Ends every PHPUnit test with understudy's own bookkeeping done for it.
final class CheckoutTest extends TestCase
{
use UnderstudyPHPUnitIntegration;
public function testChargesForTheCart(): void
{
$books = Understudy::for(BookRepositoryInterface::class);
expect(fn () => $books->find(7))->returns($expected = new Book(7));
$receipt = (new Checkout($books))->charge([7]);
self::assertSame($expected->price, $receipt->total);
}
}One registration says both things: find(7) must be called exactly once, and it answers $expected. Two rules of the engine decide that shape, and this snippet used to break both:
- Arm before the run. An
expect()counts only the calls that arrive after it is declared. Written below the action it counts zero and fails as "called never" about a call that did happen; to claim a call that has already happened, useverify(). - One registration per call. A
when()stub and anexpect()naming the same call are two registrations of one call, and the engine answers withConflictingExpectation.
Kept in step with the README's Usage section and examples/readme-usage.php, which runs it; DocumentedUsageTest fails when the three drift apart.
On a test that reached PHPUnit\Framework\TestCase::assertPostConditions() — that is, passed its body — the whole context is verified: an expect() the code never fulfilled fails the test as an assertion failure. A test whose body threw keeps its own exception untouched; verification would only mask the error that actually happened. Either way the context is reset, so nothing leaks into the next test.
A base class may flip strict stubbing for a whole project by overriding PhpUnit\understudyStrictStubs().
If the class also overrides assertPostConditions() itself, PHP resolves the conflict silently in favour of the class — the trait's verification would stop running without any error. Compose explicitly instead:
use Rasuvaeff\Understudy\PhpUnit\UnderstudyPHPUnitIntegration {
UnderstudyPHPUnitIntegration::assertPostConditions
as understudyAssertPostConditions;
}
protected function assertPostConditions(): void
{
// your post-conditions ...
$this->understudyAssertPostConditions();
}The user's post-conditions run first — the check closer to the test body wins, same as the README says.
No public members beyond what is documented above.