<?php
class User {
public function __construct(
private Base $base,
) {
}
public function run() {
$return = $this->base->f(42);
var_dump($return);
}
}
readonly class Base {
public function __construct(
public int $i,
) {
}
public function f(int $i): string {
echo $i;
return 'hoge';
}
}
class ExpectationException extends \Exception {}
readonly class Mock extends Base {
public function __construct(
private ExpectationStorage $storage = new ExpectationStorage,
) {
}
public function f(...$args): string {
if ($args !== $this->storage->getArgs(__FUNCTION__)) {
throw new ExpectationException;
}
if ($this->storage->hasReturns(__FUNCTION__)) {
return $this->storage->getReturns(__FUNCTION__);
}
}
public function expects(): ExpectationBuilder {
return new ExpectationBuilder($this->storage);
}
}
class ExpectationBuilder {
public function __construct(
private ExpectationStorage $storage,
) {
}
public function __call(string $function_name, $args) {
$this->storage->setArgs($function_name, $args);
return new FunctionExpectationBuilder($function_name, $this->storage);
}
}
class FunctionExpectationBuilder {
public function __construct(
private string $function_name,
private ExpectationStorage $storage,
) {
}
public function andReturns($value) {
$this->storage->setReturns($this->function_name, $value);
return $this;
}
}
class ExpectationStorage {
private array $args_expectations = [];
private array $returns_expectations = [];
public function setArgs(string $function_name, $args) {
$this->args_expectations[$function_name] = $args;
}
public function getArgs(string $function_name) {
return $this->args_expectations[$function_name];
}
public function setReturns(string $function_name, $value) {
$this->returns_expectations[$function_name] = $value;
}
public function getReturns(string $function_name) {
return $this->returns_expectations[$function_name];
}
public function hasReturns(string $function_name) {
return isset($this->returns_expectations[$function_name]);
}
}
$mock = new Mock();
$mock->expects()->f(42)->andReturns('nya-n');
(new User($mock))->run();
$mock = new Mock();
$mock->expects()->f(128)->andReturns('nya-n');
(new User($mock))->run();
string(5) "nya-n"
Fatal error: Uncaught ExpectationException in /in/bivtj:38
Stack trace:
#0 /in/bivtj(10): Mock->f(42)
#1 /in/bivtj(110): User->run()
#2 {main}
thrown in /in/bivtj on line 38
Process exited with code 255.
Output for 8.1.0 - 8.1.26
Parse error: syntax error, unexpected token "readonly", expecting end of file in /in/bivtj on line 15
Process exited with code 255.