How can I reset the expects() for a PHPUnit Mock?
I have a mock of the SoapClient that I would like to call multiple times within a test, resetting the expectations of each run.
$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');
With a bit more of an investigation, it seems you just call expect() again.
However, the issue with the example is the usage of $this->once(). For the duration of the test, the counter associated with expects() can not be reset. To combat this, you have a couple of options.
The first option is to ignore the number of times it gets called with $this->any().
The second option is to target the call with the usage of $this->at($x). Remember that $this->at($x) is the number of times the mock object gets called, not the particular method, and starts at 0.
With my specific example, because the mock test is the same both times, and is only expected to be called twice, I can also use $this->exactly(), with only one expects() statement. i.e.
$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');
Kudos for this answer that assisted with $this->at() and $this->exactly()
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With