如何修复抛出 BadMethodCallException 的嘲弄模拟对象?
How to fix mockery mock object throwing BadMethodCallException?
在 silex 应用程序中我有一个 KafkaAPiClient
class 肯定有 public 方法 postMessages
.
<?php
namespace Kopernikus\KafkaWriter;
use Kopernikus\KafkaWriter\Model\AbstractMessage;
/**
* KafkaApiClient.
**/
class KafkaApiClient
{
/**
* @param AbstractMessage[] $msg
*/
public function postMessages(array $messages)
{
foreach ($messages as $message) {
$this->postMessage($message);
}
}
public function postMessage(AbstractMessage $msg)
{
...
}
}
我可以很好地调用 KafkaAPiClient::postMessages
,但是在测试中模拟 class 时:
<?php
namespace unit\Request;
use Kopernikus\KafkaWriter\KafkaApiClient;
/**
* MockeryMethodsNotBeingCallableTest
**/
class MockeryMethodsNotBeingCallableTest extends \PHPUnit_Framework_TestCase
{
public function testMockMethodIsCallable()
{
$leMock = \Mockery::mock(KafkaApiClient::class);
$leMock->postMessages([]);
}
}
我得到:
1) unit\Request\MockeryMethodsNotBeingCallableTest::testMockMethodIsCallable
BadMethodCallException: Method Mockery_11_Kopernikus_KafkaWriter_KafkaApiClient::postMessages() does not exist on this mock object
~/le-project/tests/unit/Request/MockeryMethodsNotBeingCallableTest.php:14
我很困惑,我原以为模拟不会做任何事情,但允许调用方法,以便我以后可以在上面添加我的期望。
虽然我找到了解决办法,但我仍然想知道是否可以默认模拟所有方法,然后再检查是否调用了某些方法。
模拟对象上存在 shouldIgnoreMissing
方法。调用确实 exactly what it says on the tin,即:忽略对尚未定义的方法的调用,导致模拟不执行任何操作:
$leMock = \Mockery::mock(KafkaApiClient::class);
$leMock->shouldIgnoreMissing()
$leMock->postMessages([]);
毫无意义,毫无意义。当我以这种方式实例化模拟时,我的队列遇到了另一个错误,因为默认情况下方法将 return null
并且必须明确说明它们的 return 值。
$msg = new Message('dummy-message');
$this->kafkaQueue
->shouldIgnoreMissing()
->shouldReceive('getMessages')->andReturn([$msg]);
任何对 getMessages
的调用现在都会 return 恰好是数组 [$msg]
。
或者,可以通过添加 shouldReceive
:
来非常明确地说明用 Mockery 调用了哪些方法
public function testMockMethodIsCallable()
{
$leMock = \Mockery::mock(KafkaApiClient::class);
$leMock->shouldReceive('postMessages');
$leMock->postMessages([]);
}
在 silex 应用程序中我有一个 KafkaAPiClient
class 肯定有 public 方法 postMessages
.
<?php
namespace Kopernikus\KafkaWriter;
use Kopernikus\KafkaWriter\Model\AbstractMessage;
/**
* KafkaApiClient.
**/
class KafkaApiClient
{
/**
* @param AbstractMessage[] $msg
*/
public function postMessages(array $messages)
{
foreach ($messages as $message) {
$this->postMessage($message);
}
}
public function postMessage(AbstractMessage $msg)
{
...
}
}
我可以很好地调用 KafkaAPiClient::postMessages
,但是在测试中模拟 class 时:
<?php
namespace unit\Request;
use Kopernikus\KafkaWriter\KafkaApiClient;
/**
* MockeryMethodsNotBeingCallableTest
**/
class MockeryMethodsNotBeingCallableTest extends \PHPUnit_Framework_TestCase
{
public function testMockMethodIsCallable()
{
$leMock = \Mockery::mock(KafkaApiClient::class);
$leMock->postMessages([]);
}
}
我得到:
1) unit\Request\MockeryMethodsNotBeingCallableTest::testMockMethodIsCallable
BadMethodCallException: Method Mockery_11_Kopernikus_KafkaWriter_KafkaApiClient::postMessages() does not exist on this mock object
~/le-project/tests/unit/Request/MockeryMethodsNotBeingCallableTest.php:14
我很困惑,我原以为模拟不会做任何事情,但允许调用方法,以便我以后可以在上面添加我的期望。
虽然我找到了解决办法,但我仍然想知道是否可以默认模拟所有方法,然后再检查是否调用了某些方法。
模拟对象上存在 shouldIgnoreMissing
方法。调用确实 exactly what it says on the tin,即:忽略对尚未定义的方法的调用,导致模拟不执行任何操作:
$leMock = \Mockery::mock(KafkaApiClient::class);
$leMock->shouldIgnoreMissing()
$leMock->postMessages([]);
毫无意义,毫无意义。当我以这种方式实例化模拟时,我的队列遇到了另一个错误,因为默认情况下方法将 return null
并且必须明确说明它们的 return 值。
$msg = new Message('dummy-message');
$this->kafkaQueue
->shouldIgnoreMissing()
->shouldReceive('getMessages')->andReturn([$msg]);
任何对 getMessages
的调用现在都会 return 恰好是数组 [$msg]
。
或者,可以通过添加 shouldReceive
:
public function testMockMethodIsCallable()
{
$leMock = \Mockery::mock(KafkaApiClient::class);
$leMock->shouldReceive('postMessages');
$leMock->postMessages([]);
}