Methods PHPUnit mocks-assert方法调用
我是phpunit的新手,读过关于模拟对象的文档,但不太清楚 我正试图编写一个简单的测试来断言调用类中的方法。使用以下代码,我正在测试当调用Client::exchangeArray时,是否调用了Client::getInputFilterMethods PHPUnit mocks-assert方法调用,methods,mocking,phpunit,Methods,Mocking,Phpunit,我是phpunit的新手,读过关于模拟对象的文档,但不太清楚 我正试图编写一个简单的测试来断言调用类中的方法。使用以下代码,我正在测试当调用Client::exchangeArray时,是否调用了Client::getInputFilter class Client implements InputFilterAwareInterface { public function getInputFilter() { if(!$this->_inputFilter){
class Client implements InputFilterAwareInterface
{
public function getInputFilter() {
if(!$this->_inputFilter){
$inputFactory = new InputFactory();
$inputFilter = new InputFilter();
$inputFilter->add($inputFactory->createInput(array(
'name' => 'id',
'required' => true,
'filters' => array(
array(
'name' => 'Int'
)
)
)));
$inputFilter->add($inputFactory->createInput(array(
'name' => 'name',
'required' => true,
'filters' => array(
array(
'name' => 'StripTags'
),
array(
'name' => 'StringTrim'
),
array(
'name' => 'StripNewLines'
),
array(
'name' => 'Alpha'
)
),
'validators' => array(
array(
'name' => 'StringLength',
'options' => array(
'encoding' => 'UTF-8',
'min' => 2,
'max' => 100
)
)
)
)));
$inputFilter->add($inputFactory->createInput(array(
'name' => 'surname',
'required' => true,
'filters' => array(
array(
'name' => 'StripTags'
),
array(
'name' => 'StringTrim'
)
),
'validators' => array(
array(
'name' => 'StringLength',
'options' => array(
'encoding' => 'UTF-8',
'min' => 2,
'max' => 100
)
)
)
)));
$inputFilter->add($inputFactory->createInput(array(
'name' => 'email',
'required' => false,
'filters' => array(
array(
'name' => 'StripTags'
),
array(
'name' => 'StringTrim'
)
),
'validators' => array(
array(
'name' => 'StringLength',
'options' => array(
'encoding' => 'UTF-8',
'min' => 2,
'max' => 150
)
),
array(
'name' => 'EmailAddress'
)
)
)));
$this->_inputFilter = $inputFilter;
}
return $this->_inputFilter;
}
public function exchangeArray($data){
$inputFilter = $this->getInputFilter();
$inputFilter->setData($data);
if(!$inputFilter->isValid()){
throw new \Exception('Invalid client data');
}
$cleanValues = $inputFilter->getValues();
$this->_id = (isset($cleanValues['id']) ? $cleanValues['id'] : null);
$this->_name = (isset($cleanValues['name']) ? $cleanValues['name'] : null);
$this->_surname = (isset($cleanValues['surname']) ? $cleanValues['surname'] : null);
$this->_email = (isset($cleanValues['email']) ? $cleanValues['email'] : null);
}
}
以下是我的测试用例:
public function testExchangeArrayCallsInputFilter(){
$data = array('id' => 54,
'name' => 'john',
'surname' => 'doe',
'email' => 'john.doe@domain.com'
);
$mock = $this->getMock('Client', array('exchangeArray'));
$mock->expects($this->once())
->method('getInputFilter');
$mock->exchangeArray($data);
}
…我得到了以下错误:
方法名称等于的预期失败
调用1次时。方法应被调用1次,
实际上打了0次电话
我哪里出错了?这完全取决于您想要什么测试和想要什么模拟。基于测试的名称,我假设您需要测试
exchangeArray
方法
getMock
方法将要模拟的方法的名称作为第二个参数。这意味着他们永远不会被召唤
因此,如果您想要测试exchangeArray
方法和模拟getInputFilter
,您应该在第二个参数中传递“getInputFilter”,如下所示:
$mock = $this->getMock('Client', array('getInputFilter'));
$mock->expects($this->once())
->method('getInputFilter');
$mock->exchangeArray($data);
但是要小心。您没有告诉您的mock返回任何内容,因此它将返回null值。这意味着您将在exchangeArray
方法的第二行出现致命错误(尝试在非对象上调用方法)。你应该准备一些伪造的过滤对象来处理,例如:
// $preparedFilterObject = ...
$mock = $this->getMock('Client', array('getInputFilter'));
$mock->expects($this->once())
->method('getInputFilter')
->will($this->returnValue($preparedFilterObject);
$mock->exchangeArray($data);
如果你想调用“real”
getInputFilter
方法,那么你就不能模仿这个方法。谢谢你的回复。我已经有了这两种方法的实现。我只是想检查方法的调用顺序是否正确,然后检查是否使用特定参数调用它们。有没有办法检查在没有模拟对象的情况下调用方法?没有。但是,如果你想调用第二个方法,你不需要检查它是否真的被调用了,因为如果它没有被调用,那么你就不会得到$inputFilter对象,你的测试也会失败。另一方面,如果你的测试通过了,第二个方法没有被调用(在你的情况下不会发生,但在某些情况下可能发生),你会在代码覆盖率报告中注意到这一点。这可能意味着你不需要第二次呼叫,或者你已经修复了测试。如果您的第二个方法设置了一些内部对象属性,您还可以针对该属性进行测试,以检查是否调用了该方法。