cb = Closure::fromCallable($cb); } public static function make(callable $cb): static { return new static($cb); } public function __invoke(mixed ...$args): mixed { $call = new TestCall( args: $args, return: ($this->cb)(...$args), ); $this->calls[] = $call; return $call->return; } public function getCallCount(): int { return count($this->calls); } /** @return TestCall[] */ public function getCalls(): array { return $this->calls; } public function getLastCall(): ?TestCall { return $this->calls[$this->getCallCount() - 1] ?? null; } public function assertCalled(): void { Assert::assertGreaterThan(0, $this->getCallCount(), 'Not been called'); } public function assertNotCalled(): void { Assert::assertSame(0, $this->getCallCount()); } public function assertCalledTimes(int $amount): void { Assert::assertSame($amount, $this->getCallCount()); } }