2009-09-28 12 views
30

निम्न वर्ग को देखते हुए:PHPUnit: सत्यापित करना कि सरणी में दिए गए मान के साथ एक कुंजी है

<?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' नामक एक कुंजी है 'मान 1' का मूल्य?

मैं सभी सरणी को सत्यापित नहीं करना चाहता - यह केवल एक नमूना कोड है, वास्तविक कोड में पास किए गए सरणी में बहुत अधिक मूल्य हैं, मैं वहां केवल एक कुंजी/मूल्य जोड़ी को सत्यापित करना चाहता हूं।

$this->arrayHasKey('keyname') है जिसका उपयोग मैं यह सत्यापित करने के लिए कर सकता हूं कि कुंजी मौजूद है।

$this->contains('Value 1') भी है, जिसका उपयोग यह सत्यापित करने के लिए किया जा सकता है कि सरणी में यह मान है।

मैं उन दोनों को $this->logicalAnd के साथ भी जोड़ सकता हूं। लेकिन यह निश्चित रूप से वांछित परिणाम नहीं देता है।

अब तक मैं रिटर्नकॉलबैक का उपयोग कर रहा हूं, पूरे $ पैरा को कैप्चर कर रहा हूं और उसके बाद उस पर जोर दे रहा हूं, लेकिन क्या मैं शायद ऐसा करने का दूसरा तरीका हूं?

+1

$ यह-> विशेषता (बाधा, मूल्य) जो मैं कर रहा हूं वह करने में सक्षम है, लेकिन यह सरणी पर काम नहीं करती है। –

उत्तर

7

मैं एक

विशेषता के आधार पर अपनी खुद की बाधा वर्ग बना रहा
<?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)); 
+2

उस सुविधा के लिए अनुरोध खींचें: https://github.com/sebastianbergmann/phpunit/pull/312 – cweiske

-2

क्षमा करें, मैं एक अंग्रेजी स्पीकर नहीं हूं।

मुझे लगता है कि आप एक प्रमुख array_key_exists समारोह के साथ सरणी में मौजूद रहने पर परीक्षण कर सकते हैं, और यदि मूल्य array_search

उदाहरण के लिए के साथ मौजूद है आप परीक्षण कर सकते हैं:

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

उपयोग !== क्योंकि array_search यदि मौजूद है तो उस मान की कुंजी लौटाएं और यह 0

+6

मुझे वह सब पता है, लेकिन मैं PHPUnit के अंदर एक जोर स्थापित करना चाहता हूं। –

15

एक फिर से प्रयोग करने योग्य बाधा वर्ग बनाने के एवज में, मैं 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 इसके निर्माता में एक प्रतिदेय उम्मीद, और बस मूल्यांकन के दौरान यह आह्वान: यहाँ है कि मैं क्या के साथ आया है। यह दावा इस आधार पर गुजरता है या विफल रहता है कि कॉल करने योग्य सही या गलत है या नहीं।

एक बड़ी परियोजना के लिए, मैं निश्चित रूप से PHPUnit में विलय करने के लिए PR #312 के लिए पुन: प्रयोग करने योग्य बाधा (या उपरोक्त समाधान में) की याचिका बनाने की सिफारिश करता हूं, लेकिन यह एक बार की आवश्यकता के लिए चाल है। यह देखना आसान है कि कॉलबैक बाधा अधिक जटिल दावों के लिए भी उपयोगी कैसे हो सकती है।

+0

क्या यह संभव है कि 'कॉलबैक' contrain के भीतर 'assert * 'रखा जाए? – jjoselon

30

$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

मामले में आप पैरामीटर पर कुछ जटिल परीक्षण करना चाहते हैं, और भी उपयोगी संदेशों और तुलना है, वहाँ हमेशा रखने के दावे करने का विकल्प है कॉलबैक के भीतर।

उदा।

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

ध्यान दें कि कॉलबैक सत्य लौटाता है। अन्यथा, यह हमेशा असफल होगा।

संबंधित मुद्दे