PHPUnit 测试存根方法可以不被覆盖吗?

Can PHPUnit test stub methods not be overwritten?

在我的测试中,我为 class 创建了一个测试存根,并将方法 "save" 的输出模拟为 return 默认值。我在我的 setUp() 方法中有这个在每次测试运行之前启动:

//  auth adapter
$this->authMock = $this->getMockBuilder('App\Auth')
    ->disableOriginalConstructor()
    ->getMock();

// by defaut, we'll make authenticate return a FAIL result
$this->authMock
    ->method('authenticate')
    ->willReturn(0);

然后将其注入我的服务定位器,覆盖应用程序使用的服务定位器(真正的 App\Auth)。但是,在实际测试中,我可能希望更改该方法的输出

// here, we'll make authenticate return a SUCCESS result
$this->authMock
    ->method('authenticate')
    ->willReturn(1);

无论如何,一旦我确定了问题,对于 POC,我只是将它们一个接一个地放置并且足够正确,似乎 PHPUnit 不允许我覆盖先前声明的模拟方法 return 值:

//  auth adapter
$this->authMock = $this->getMockBuilder('App\Auth')
    ->disableOriginalConstructor()
    ->getMock();

// by defaut, we'll make authenticate return a FAIL result
$this->authMock
    ->method('authenticate')
    ->willReturn(0);

// here, we'll make authenticate return a SUCCESS result
$this->authMock
    ->method('authenticate')
    ->willReturn(1);

var_dump($this->authMock->authenticate());出口; // returns 0 :(

我敢肯定,我过去能做到这一点。除非它是以前版本的 PHPUnit。目前我正在使用 4.8.*。我有什么办法可以做到这一点?默认情况下,我希望对 return FAIL 进行身份验证,但有些测试我可能想用 SUCCESS 覆盖它(因此就像用户已通过身份验证一样)

我不记得曾经能够模拟同一个方法两次,所以我通常做的是定义一个辅助函数:

protected function mockAuthResult($result = 0) {...}

另一种选择是定义:

protected $authResult;

然后在你的 setUp:

$this->authResult = 0; // fail by default
$this->authMock
    ->method('authenticate')
    ->willReturn($this->authResult);

然后您可以覆盖它以进行个别测试。