counter++; } class Handler { public function __invoke($obj) { $obj->counter++; } } $obj = new TestClass; $obj->onPublic(); $var = new stdClass; $var->counter = 0; $obj->onPublic[] = 'handler'; $obj->onPublic($var); Assert::same(1, $var->counter); $obj->onPublic[] = new Handler; $obj->onPublic($var); Assert::same(3, $var->counter); Assert::exception( fn() => $obj->onPublicStatic(123), Nette\MemberAccessException::class, 'Call to undefined method TestClass::onPublicStatic().', ); Assert::exception( fn() => $obj->onProtected(123), Nette\MemberAccessException::class, 'Call to undefined method TestClass::onProtected().', ); Assert::exception( fn() => $obj->onPrivate(123), Nette\MemberAccessException::class, 'Call to undefined method TestClass::onPrivate().', ); Assert::exception( fn() => $obj->onUndefined(123), Nette\MemberAccessException::class, 'Call to undefined method TestClass::onUndefined().', ); Assert::exception(function () use ($obj) { $obj->onPublic = 'string'; $obj->onPublic(); }, Nette\UnexpectedValueException::class, 'Property TestClass::$onPublic must be iterable or null, string given.'); $obj = new TestClass; Assert::noError(fn() => $obj->onEvent());