[英]PHPUnit: Verifying that array has a key with given value
鉴于以下类:
<?php
class Example {
private $Other;
public function __construct ($Other)
{
$this->Other = $Other;
}
public function query ()
{
$params = array(
'key1' => 'Value 1'
, 'key2' => 'Value 2'
);
$this->Other->post($params);
}
}
这个测试用例:
<?php
require_once 'Example.php';
require_once 'PHPUnit/Framework.php';
class ExampleTest extends PHPUnit_Framework_TestCase {
public function test_query_key1_value ()
{
$Mock = $this->getMock('Other', array('post'));
$Mock->expects($this->once())
->method('post')
->with(YOUR_IDEA_HERE);
$Example = new Example($Mock);
$Example->query();
}
我如何验证$params
(它是一个数组)并传递给$Other->post()
包含一个名为“key1”的键,它的值为“Value 1”?
我不想验证所有数组 - 这只是一个示例代码,在实际代码中,传递的数组有更多值,我只想验证其中的单个键/值对。
我可以使用$this->arrayHasKey('keyname')
来验证密钥是否存在。
还有$this->contains('Value 1')
,可用于验证数组是否具有此值。
我什$this->logicalAnd
可以将这两者与$this->logicalAnd
结合起来。 但这当然不会给出预期的结果。
到目前为止,我一直在使用 returnCallback,捕获整个 $params 然后对其进行断言,但是也许有另一种方法可以做我想做的事?
$this->arrayHasKey('keyname');
方法存在,但其名称为assertArrayHasKey
:
// In your PHPUnit test method
$hi = array(
'fr' => 'Bonjour',
'en' => 'Hello'
);
$this->assertArrayHasKey('en', $hi); // Succeeds
$this->assertArrayHasKey('de', $hi); // Fails
代替创建可重用的约束类,我能够使用PHPUnit中现有的回调约束来声明数组键的值。 在我的用例中,我需要在模拟方法的第二个参数中检查数组值( MongoCollection :: ensureIndex() ,如果有人好奇的话)。 这是我想出的:
$mockedObject->expects($this->once())
->method('mockedMethod')
->with($this->anything(), $this->callback(function($o) {
return isset($o['timeout']) && $o['timeout'] === 10000;
}));
回调约束在其构造函数中期望有一个可调用的对象,并且在评估期间仅调用它。 根据可调用对象返回的是true还是false,断言是通过还是失败。
对于大型项目,我当然会建议创建一个可重用的约束(如上述解决方案中所述)或请求将PR#312合并到PHPUnit中,但这确实满足了一次性需要。 很容易看出,回调约束对于更复杂的断言也可能很有用。
我最终根据属性一创建了自己的约束类
<?php
class Test_Constraint_ArrayHas extends PHPUnit_Framework_Constraint
{
protected $arrayKey;
protected $constraint;
protected $value;
/**
* @param PHPUnit_Framework_Constraint $constraint
* @param string $arrayKey
*/
public function __construct(PHPUnit_Framework_Constraint $constraint, $arrayKey)
{
$this->constraint = $constraint;
$this->arrayKey = $arrayKey;
}
/**
* Evaluates the constraint for parameter $other. Returns TRUE if the
* constraint is met, FALSE otherwise.
*
* @param mixed $other Value or object to evaluate.
* @return bool
*/
public function evaluate($other)
{
if (!array_key_exists($this->arrayKey, $other)) {
return false;
}
$this->value = $other[$this->arrayKey];
return $this->constraint->evaluate($other[$this->arrayKey]);
}
/**
* @param mixed $other The value passed to evaluate() which failed the
* constraint check.
* @param string $description A string with extra description of what was
* going on while the evaluation failed.
* @param boolean $not Flag to indicate negation.
* @throws PHPUnit_Framework_ExpectationFailedException
*/
public function fail($other, $description, $not = FALSE)
{
parent::fail($other[$this->arrayKey], $description, $not);
}
/**
* Returns a string representation of the constraint.
*
* @return string
*/
public function toString ()
{
return 'the value of key "' . $this->arrayKey . '"(' . $this->value . ') ' . $this->constraint->toString();
}
/**
* Counts the number of constraint elements.
*
* @return integer
*/
public function count ()
{
return count($this->constraint) + 1;
}
protected function customFailureDescription ($other, $description, $not)
{
return sprintf('Failed asserting that %s.', $this->toString());
}
可以这样使用:
... ->with(new Test_Constraint_ArrayHas($this->equalTo($value), $key));
如果您希望对参数进行一些复杂的测试,并获得有用的消息和比较结果,则始终可以选择在回调中放置断言。
例如
$clientMock->expects($this->once())->method('post')->with($this->callback(function($input) {
$this->assertNotEmpty($input['txn_id']);
unset($input['txn_id']);
$this->assertEquals($input, array(
//...
));
return true;
}));
请注意,回调返回true。 否则,它将始终失败。
如果您不介意在密钥不存在(而不是失败)时出现错误,那么您可以使用以下方法。
$this->assertEquals('Value 1', $params['key1']);
抱歉,我不会说英语。
我认为您可以使用array_key_exists函数测试数组中是否存在键,并且可以使用array_search测试值是否存在
例如:
function checkKeyAndValueExists($key,$value,$arr){
return array_key_exists($key, $arr) && array_search($value,$arr)!==false;
}
使用!==
因为array_search返回该值的键(如果存在),并且可以为0。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.