代码之家  ›  专栏  ›  技术社区  ›  Anti Veeranna

PHPUnit:验证数组是否具有具有给定值的键

  •  32
  • Anti Veeranna  · 技术社区  · 15 年前

    鉴于以下类别:

    <?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

    到目前为止,我一直在使用returnCallback,捕获整个$params,然后对其进行断言,但是是否有其他方法可以实现我想要的呢?

    5 回复  |  直到 12 年前
        1
  •  52
  •   air-dex    10 年前

    这个 $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
    
        2
  •  16
  •   jmikola    12 年前

    我能够使用PHPUnit中现有的回调约束断言数组键的值,而不是创建一个可重用的约束类。在我的用例中,我需要在模拟方法的第二个参数中检查数组值( MongoCollection::ensureIndex() ,如果有人好奇的话)。以下是我的想法:

    $mockedObject->expects($this->once())
        ->method('mockedMethod')
        ->with($this->anything(), $this->callback(function($o) {
            return isset($o['timeout']) && $o['timeout'] === 10000;
        }));
    

    这个 callback constraint 在其构造函数中需要一个可调用的,并在求值期间简单地调用它。断言是否通过取决于可调用函数是否返回true或false。

    PR #312

        3
  •  8
  •   Anti Veeranna    15 年前

    最后,我基于属性1创建了自己的约束类

    <?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));
    
        4
  •  3
  •   Dane Lowe    8 年前

    例如

    $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;
    }));
    

        5
  •  -4
  •   BenMorel mehmet cinar    11 年前

    我认为您可以使用array\u key\u exists函数测试数组中是否存在键,并且可以使用array\u search测试值是否存在

    function checkKeyAndValueExists($key,$value,$arr){
        return array_key_exists($key, $arr) && array_search($value,$arr)!==false;
    }
    

    使用 !==