问题描述
我曾经有过这样的PHPUnit代码(由于我无法重写它,可能不是一个好代码):
$authorizator->expects($this->at(0))
->method('isAllowed')
->willReturn($hasSuperPrivilege);
if (!$hasSuperPrivilege) {
$authorizator->expects($this->at(1))
->method('isAllowed')
->willReturn($hasstandardPrivilege);
}
在弃用at()方法后如何实现相同的行为?
我不知道该方法将被调用多少次,所以willReturnOnConsecutiveCalls方式可能不合适吗?
如果第一次调用返回false,则isAllowed()方法必须调用两次,如果返回true,则只能调用一次。
相关问题:https://github.com/sebastianbergmann/phpunit/issues/4297
经过测试的方法:
public function canUserdoSomething(Foo $resource,Identity $identity): bool
{
if (
$this->authorizator->isAllowed(
$identity,$resource,'superPrivilege'
)
) {
return true;
}
if (
$this->authorizator->isAllowed(
$identity,'standardPrivilege'
)
) {
return $resource->hasSomeproperty();
}
return false;
}
解决方法
我会带手写的假冒品,所以您不必担心打来的电话。为了简洁起见,我在示例中内联了代码,但是如果您在多个测试中使用authorizator,则将其提取到一个单独的类中是很有意义的。
/**
* @covers \MyClass
*/
class MyClassTest extends TestCase
{
private $subject;
private $authorizator;
/**
* @testWith ["superPrivilege",false,true]
* ["standardPrivilege",true,false]
* ["invalidPrivilege",false]
*/
public function testCanUserdoSomething($privelege,$resourceProperty,$expected)
{
$identity = new Identity();
$resource = new Foo($resourceProperty);
$this->authorizator->addPrivilege($identity,$resource,$privelege);
$result = $this->subject->canUserdoSomething($resource,$identity);
self::assertEquals($expected,$result);
}
protected function setUp(): void
{
parent::setUp();
$this->authorizator = new class implements Authorizator {
private $privileges = [];
public function addPrivilege(Identity $identity,Foo $resource,string $privilege): void
{
$this->privileges[] = spl_object_id($identity) . spl_object_id($resource) . $privilege;
}
public function isAllowed(Identity $identity,string $privilege): bool
{
return in_array(spl_object_id($identity) . spl_object_id($resource) . $privilege,$this->privileges);
}
};
$this->subject = new MyClass($this->authorizator);
}
}