如何使用 PHPUnit 重置模拟对象


How to reset a Mock Object with PHPUnit

如何重置 PHPUnit 模拟的 expects()?

我有一个 SoapClient 的模拟,我想在测试中多次调用它,重置每次运行的期望。

$soapClientMock = $this->getMock('SoapClient', array('__soapCall'), array($this->config['wsdl']));
$this->Soap->client = $soapClientMock;
// call via query
$this->Soap->client->expects($this->once())
    ->method('__soapCall')
    ->with('someString', null, null)
    ->will($this->returnValue(true));
$result = $this->Soap->query('someString'); 
$this->assertFalse(!$result, 'Raw query returned false');
$source = ConnectionManager::create('test_soap', $this->config);
$model = ClassRegistry::init('ServiceModelTest');
// No parameters
$source->client = $soapClientMock;
$source->client->expects($this->once())
    ->method('__soapCall')
    ->with('someString', null, null)
    ->will($this->returnValue(true));
$result = $model->someString();
$this->assertFalse(!$result, 'someString returned false');

通过更多的调查,似乎你只是再次调用 expect()。

但是,该示例的问题是使用 $this->once()。 在测试期间,无法重置与 expects() 关联的计数器。 为了解决这个问题,您有几个选择。

第一个选项是忽略使用 $this->any() 调用它的次数。

第二个选项是使用 $this->at($x) 来定位呼叫。 请记住,$this->at($x) 是调用模拟对象的次数,而不是特定方法,从 0 开始。

通过我的具体示例,由于模拟测试两次都相同,并且预计只会调用两次,所以我也可以使用 $this->exactly(),只有一个 expects() 语句。

$soapClientMock = $this->getMock('SoapClient', array('__soapCall'), array($this->config['wsdl']));
$this->Soap->client = $soapClientMock;
// call via query
$this->Soap->client->expects($this->exactly(2))
    ->method('__soapCall')
    ->with('someString', null, null)
    ->will($this->returnValue(true));
$result = $this->Soap->query('someString'); 
$this->assertFalse(!$result, 'Raw query returned false');
$source = ConnectionManager::create('test_soap', $this->config);
$model = ClassRegistry::init('ServiceModelTest');
// No parameters
$source->client = $soapClientMock;
$result = $model->someString();
$this->assertFalse(!$result, 'someString returned false');

感谢这个帮助$this->at()和$this->确切()的答案

您可以清除这样的模拟:

// Verify first
$mock->mockery_verify();
        
// and then overwrite with empty expectation directors 
foreach(array_keys($mock->mockery_getExpectations()) as $method) {
    $mock->mockery_setExpectationsFor($method, new Mockery'ExpectationDirector($method, $mock));
}