php PHPUnit:验证数组是否具有具有给定值的键
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1487296/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
PHPUnit: Verifying that array has a key with given value
提问by Anti Veeranna
Given the following class:
鉴于以下类:
<?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);
}
}
And this testcase:
这个测试用例:
<?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();
}
How do I verify that $params(which is an array) and is passed to $Other->post()contains a key named 'key1' that has a value of 'Value 1'?
我如何验证$params(它是一个数组)并传递给$Other->post()包含一个名为“key1”且值为“Value 1”的键?
I do not want to verify all of the array - this is just a sample code, in actual code the passed array has a lot more values, I want to verify just a single key/value pair in there.
我不想验证所有数组 - 这只是一个示例代码,在实际代码中,传递的数组有更多值,我只想验证其中的单个键/值对。
There is $this->arrayHasKey('keyname')that I can use to verify that the key exists.
还有$this->arrayHasKey('keyname'),我可以用它来验证该键存在。
There is also $this->contains('Value 1'), which can be used to verify that the array has this value.
还有$this->contains('Value 1'),可用于验证数组是否具有此值。
I could even combine those two with $this->logicalAnd. But this of course does not give the desired result.
我什至可以将这两者与$this->logicalAnd. 但这当然不会给出预期的结果。
So far I have been using returnCallback, capturing the whole $params and then doing asserts on that, but is there perhaps another way to do what I want?
到目前为止,我一直在使用 returnCallback,捕获整个 $params 然后对其进行断言,但是也许有另一种方法可以做我想做的事?
采纳答案by Anti Veeranna
I ended up creating my own constraint class, based on the attribute one
我最终基于属性 one 创建了自己的约束类
<?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());
}
It can be used like this:
它可以像这样使用:
... ->with(new Test_Constraint_ArrayHas($this->equalTo($value), $key));
回答by air-dex
The $this->arrayHasKey('keyname');method exists but its name is assertArrayHasKey:
该$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
回答by jmikola
In lieu of creating a re-usable constraint class, I was able to assert an array key's value using the existing callback constraint in PHPUnit. In my use case, I needed to check for an array value in the second argument to a mocked method (MongoCollection::ensureIndex(), if anyone is curious). Here's what I came up with:
代替创建可重用的约束类,我能够使用 PHPUnit 中现有的回调约束来断言数组键的值。在我的用例中,我需要检查模拟方法(MongoCollection::ensureIndex(),如果有人好奇的话)的第二个参数中的数组值。这是我想出的:
$mockedObject->expects($this->once())
->method('mockedMethod')
->with($this->anything(), $this->callback(function($o) {
return isset($o['timeout']) && $o['timeout'] === 10000;
}));
The callback constraintexpects a callable in its constructor, and simply invokes it during evaluation. The assertion passes or fails based on whether the callable returns true or false.
该回调约束预计它的构造函数调用,和评估过程中简单地调用它。断言通过或失败取决于可调用对象是返回 true 还是 false。
For a large project, I'd certainly recommend creating a re-usable constraint (as in the above solution) or petitioning for PR #312to be merged into PHPUnit, but this did the trick for a one-time need. It's easy to see how the callback constraint might be useful for more complicated assertions, too.
对于大型项目,我当然会建议创建一个可重用的约束(如上述解决方案中)或请求将PR #312合并到 PHPUnit 中,但这对一次性需求起到了作用。很容易看出回调约束对于更复杂的断言也很有用。
回答by Dane Lowe
In case you wish to do some complex testing on the parameter, and also have useful messages and comparisons, there is always the option of placing assertions within the callback.
如果您希望对参数进行一些复杂的测试,并希望获得有用的消息和比较,则始终可以选择在回调中放置断言。
e.g.
例如
$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;
}));
Notice that the callback returns true. Otherwise, it would always fail.
请注意,回调返回 true。否则,它总是会失败。
回答by Dane Lowe
Sorry, I'm not an English speaker.
对不起,我不会说英语。
I think that you can test if a key exists in the array with the array_key_exists function, and you can test if the value exists with array_search
我认为您可以使用 array_key_exists 函数测试数组中是否存在一个键,并且您可以使用 array_search 测试该值是否存在
For example:
例如:
function checkKeyAndValueExists($key,$value,$arr){
return array_key_exists($key, $arr) && array_search($value,$arr)!==false;
}
Use !==because array_search return the key of that value if exists and it may be 0.
使用!==因为 array_search 返回该值的键(如果存在并且它可能是 0)。

