2011-03-16 10 views
13

PHPUnit का उपयोग करके, मैं pdo का मज़ाक उड़ा रहा हूं, लेकिन मैं एक से अधिक डेटाबेस क्वेरी कथन तैयार करने का एक तरीका ढूंढने का प्रयास कर रहा हूं।, क्या "with" विधि के अंदर उपयोग के लिए onconsecutivecalls की तरह एक विधि है?

$pdo = $this->getPdoMock(); 
$stmt = $this->getPdoStatementMock($pdo); 

$pdo->expects($this->any()) 
    ->method('prepare') 
    ->with($this->equalTo($title_query)) 
    ->will($this->returnValue($stmt)); 

$title_stmt = $pdo->prepare($title_query); 
$desc_stmt = $pdo->prepare($desc_query); 

मैं "के साथ" विधि के लिए onConsecutiveCalls को कुछ इसी तरह पास करना चाहते हैं, तो जैसा कि ऊपर देखा मैं कई विवरण तैयार कर सकते हैं। आप यह करने के बारे में कैसे जाएंगे?

उत्तर

19

आप $this->at()$this->any() के बजाय साथ अलग उम्मीदों लिख कर एक ही विधि का लगातार आमंत्रण से मेल कर सकते हैं:

$pdo->expects($this->at(0)) 
    ->method('prepare') 
    ->with($this->equalTo($title_query)) 
    ->will($this->returnValue($stmt)); 

$pdo->expects($this->at(1)) 
    ->method('prepare') 
    ->with($this->equalTo($desc_query)) 
    ->will($this->returnValue($stmt)); 

$title_stmt = $pdo->prepare($title_query); 
$desc_stmt = $pdo->prepare($desc_query); 
+0

बिल्कुल सही! यही वह है जिसे मैं ढूंढ रहा था। अब महान काम कर रहा है। धन्यवाद! –

+6

ध्यान दें कि काउंटर प्रति * सभी * विधि कॉल में प्रति-नकली है। इस प्रकार यदि '$ pdo' में दो हस्तक्षेप करने वाले कॉल होने जा रहे हैं, तो आप 0 और 3 का उपयोग करेंगे। –

+0

@ डेविड हाँ, आप सही हैं। अभी भी उल्लेखनीय है कि केवल उन विधियों को कॉल करें जिन्हें नकली कार्यान्वयन गिनती के साथ 'वास्तव में बदल दिया गया' था। – Vika

3

केवल एक चीज मैं जैसी पाया है कि तुम क्या पूछना 'पर' का उपयोग किया जाता है:

$mock->expects($this->at(0))->method // etc 
$mock->expects($this->at(1))->method // etc 

तो आप पहली बार (0 में) यह कहा जाता है के लिए अपेक्षाएं सेट, दूसरी बार और इतने पर ।

+0

बिल्कुल सही! यही वही है जो मुझे चाहिए था। धन्यवाद! –

0

लोगों के एक जोड़े ने कहा है कि ($ इंडेक्स) पर कॉल के विशिष्ट उदाहरण के लिए इस्तेमाल किया जा सकता एक विधि के लिए। डेविड एच और वीका ने स्पष्ट किया कि $ सूचकांक ऑब्जेक्ट के सभी मॉक किए गए तरीकों के लिए सभी कॉलों की गणना करता है।

इसके अतिरिक्त, यह ध्यान देने योग्य हो सकता है कि PHPunit दस्तावेज़ के Test Doubles Chapter के बारे में एक चेतावनी नोट है। यह इंगित करता है कि() का उपयोग सावधानी के साथ किया जाना चाहिए, क्योंकि इससे भंगुर परीक्षण हो सकते हैं जो विशिष्ट कार्यान्वयन पर बहुत अधिक निर्भर करता है।

14

PHPUnit 4.1 को एक नई विधि withConsecutive() मिली। Test Double Chapter से:

class FooTest extends PHPUnit_Framework_TestCase 
{ 
    public function testFunctionCalledTwoTimesWithSpecificArguments() 
    { 
     $mock = $this->getMock('stdClass', array('set')); 
     $mock->expects($this->exactly(2)) 
      ->method('set') 
      ->withConsecutive(
       array($this->equalTo('foo'), $this->greaterThan(0)), 
       array($this->equalTo('bar'), $this->greaterThan(0)) 
      ); 

     $mock->set('foo', 21); 
     $mock->set('bar', 48); 
    } 
} 

withConsecutive() से प्रत्येक तर्क निर्दिष्ट विधि के लिए एक कॉल के लिए है।

9

PHPUnit के हाल के संस्करणों के साथ, स्वीकृत उत्तर को थोड़ा सा सरल बनाया जा सकता है।

प्लस, जबकि यह मूल प्रश्न के लिए तत्काल प्रासंगिक नहीं है, तो आप आसानी से विभिन्नwillReturnOnConsecutiveCalls विधि के माध्यम से प्रत्येक विधि आमंत्रण के लिए वापसी मान प्रदान कर सकते हैं।

$pdo->expects($this->exactly(2)) 
    ->method('prepare') 
    ->withConsecutive(
     $this->equalTo($title_query), 
     $this->equalTo($desc_query) 
    ) 
    ->willReturnOnConsecutiveCalls(
     $stmt, // returned on the 1st call to prepare() 
     $stmt // returned on the 2nd call to prepare() 
    ); 
+1

यह एक और अधिक उचित और सरल है अधिक हालिया PHPUnit संस्करणों के लिए उत्तर दें। निश्चित रूप से आसान। –

0

मैं एक dataProvider का उपयोग करें और निष्पादित प्रश्नों कि मैं अपने प्रदाता को भरने के लिए उपयोग कर सकते हैं की एक चर संख्या की जरूरत है, मैं उन क्वेरी के लिए मार डाला जाना चाहिए की एक सरणी प्रदान करना चाहते हैं। withConsecutive के साथ समस्या यह है कि यह एक चरणीय संख्या में सरणी लेता है, प्रत्येक में तर्कों की एक श्रृंखला होती है।

मैं follwing कोड का उपयोग कर इसे हल, इस का मानना ​​है "hacky" लेकिन काम कर रहा है:

$withConsecutiveArgs = [ 
    [$this->equalTo($title_query)], 
    [$this->equalTo($desc_query)], 
    ..., 
    N queries 
]; 
$withConsecutiveReturns = [ 
    $title_stmt, 
    $desc_stmt, 
    ..., 
    N returns 
]; 

$methodMock = $pdo->expects($this->exactly(count($args))->method('prepare'); 
$methodMock->getMatcher()->parametersMatcher = new \PHPUnit_Framework_MockObject_Matcher_ConsecutiveParameters($withConsecutiveArgs); 
$methodMock->will(new \PHPUnit_Framework_MockObject_Stub_ConsecutiveCalls($withConsecutiveReturns)); 

$title_stmt = $pdo->prepare($title_query); 
$desc_stmt = $pdo->prepare($desc_query); 
... 
$N_s_stmt = $pdo->prepare($N_s_query); 

मैं, आशा है कि यह PHPUnit (जो अनिश्चित है के भविष्य के संस्करणों के साथ सही ढंग से विकसित के बाद से मैं के आंतरिक भागों पर भरोसा करते हैं lib, लेकिन यूनिट टेस्ट करने का यह पूरा बिंदु है, मुझे इसे दोबारा करना पड़ सकता है लेकिन उत्पादन उस से पीड़ित नहीं होगा)

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