सवाल phpunit नकली के लिए कन्स्ट्रक्टर तर्क से बचें


एक नकली वस्तु के लिए कन्स्ट्रक्टर को कॉल करने के लिए phpunit से बचने का तरीका क्या है? अन्यथा मुझे एक मॉक ऑब्जेक्ट को कन्स्ट्रक्टर तर्क के रूप में चाहिए, इसके लिए एक और आदि। एपीआई इस तरह प्रतीत होता है:

getMock($className, $methods = array(), array $arguments = array(),
        $mockClassName = '', $callOriginalConstructor = TRUE,
        $callOriginalClone = TRUE, $callAutoload = TRUE)

मुझे यह काम नहीं मिल रहा है। यह अभी भी कन्स्ट्रक्टर तर्क के बारे में शिकायत करता है, यहां तक ​​कि साथ भी $callOriginalConstructor झूठ पर सेट करें।

मेरे पास केवल कन्स्ट्रक्टर में एक ऑब्जेक्ट है और यह एक निर्भरता इंजेक्शन है। इसलिए मुझे नहीं लगता कि मेरे पास एक डिज़ाइन समस्या है।


76
2017-11-10 23:00


मूल




जवाब:


आप उपयोग कर सकते हैं getMockBuilder बस के बजाय getMock:

$mock = $this->getMockBuilder('class_name')
    ->disableOriginalConstructor()
    ->getMock();

अनुभाग देखें "टेस्ट डबल्स" में PHPUnit के दस्तावेज ब्योरा हेतु।

यद्यपि आप यह कर सकते हैं, यह करने की आवश्यकता नहीं है। आप अपने कोड को दोबारा कर सकते हैं ताकि एक ठोस वर्ग (एक कन्स्ट्रक्टर के साथ) इंजेक्शन की आवश्यकता हो, तो आप केवल एक इंटरफ़ेस पर निर्भर करते हैं। इसका मतलब है कि आप कन्स्ट्रक्टर व्यवहार को संशोधित करने के लिए PHPUnit को बताने के बिना इंटरफ़ेस को नकल या स्टब कर सकते हैं।


125
2018-06-08 10:11



यह मेरे लिए बहुत अच्छा काम करता है। हालांकि यह उदाहरण 10.3 होना चाहिए। मैंने पोस्ट को संपादित करने की कोशिश की लेकिन एसओ ने इसे बहुत कम संपादन के लिए वापस लात मार दिया। - Matthew
धन्यवाद @ लिटिथविन। उत्तर अपडेट किया गया। - dave1010
मेरे लिए भी काम करता है। धन्यवाद! - Jeune


हेयर यू गो:

    // Get a Mock Soap Client object to work with.
    $classToMock = 'SoapClient';
    $methodsToMock = array('__getFunctions');
    $mockConstructorParams = array('fake wsdl url', array());
    $mockClassName = 'MyMockSoapClient';
    $callMockConstructor = false;
    $mockSoapClient = $this->getMock($classToMock,
                                     $methodsToMock,
                                     $mockConstructorParams,
                                     $mockClassName,
                                     $callMockConstructor);

40
2018-03-09 22:38



ऐसा लगता है कि मैं लगभग क्या चाहता हूं। मैं getMock को केवल क्लास के साथ कॉल करना चाहता हूं और $ callMockConstructor को कॉल करना चाहता हूं। कैसे? इस तरह कुछ: $ यह-> getMock ($ classToMock, $ callMockConstructor)। केवल एक चीज जिसे मैं सोच सकता हूं वह PHPUnit के स्रोत में जाना है और इसे डिफ़ॉल्ट = गलत में बदलना है। - Gutzofter
मैंने testcase.php में डिफ़ॉल्ट को गलत में बदल दिया। आपको लगता है कि यह डिफ़ॉल्ट रूप से गलत के लिए सेट किया जाएगा। एक कन्स्ट्रक्टर का मज़ाकिया बहुत अजीब लगता है - Gutzofter
ओबीटीडब्ल्यू, धन्यवाद! - Gutzofter
उत्कृष्ट जवाब मुझे इसकी ही खोज थी - Hades


एक परिशिष्ट के रूप में, मैं संलग्न करना चाहता था expects() मेरे मॉक ऑब्जेक्ट को कॉल करता है और फिर कन्स्ट्रक्टर को कॉल करता है। PHPUnit 3.7.14 में, ऑब्जेक्ट जो कॉल करते समय लौटाया जाता है disableOriginalConstructor() सचमुच एक वस्तु है।

// Use a trick to create a new object of a class
// without invoking its constructor.
$object = unserialize(
sprintf('O:%d:"%s":0:{}', strlen($className), $className)

दुर्भाग्य से, PHP 5.4 में एक नया विकल्प है जिसका उपयोग वे नहीं कर रहे हैं:

ReflectionClass :: newInstanceWithoutConstructor

चूंकि यह उपलब्ध नहीं था, इसलिए मुझे कक्षा को मैन्युअल रूप से प्रतिबिंबित करना था और फिर कन्स्ट्रक्टर का आह्वान करना पड़ा।

$mock = $this->getMockBuilder('class_name')
    ->disableOriginalConstructor()
    ->getMock();

$mock->expect($this->once())
    ->method('functionCallFromConstructor')
    ->with($this->equalTo('someValue'));

$reflectedClass = new ReflectionClass('class_name');
$constructor = $reflectedClass->getConstructor();
$constructor->invoke($mock);

नोट, अगर functionCallFromConstruct है protected, आपको विशेष रूप से उपयोग करना होगा setMethods() ताकि संरक्षित विधि मजाक हो। उदाहरण:

    $mock->setMethods(array('functionCallFromConstructor'));

setMethods() पहले कहा जाना चाहिए expect() कहते हैं। व्यक्तिगत रूप से, मैं इसके बाद श्रृंखला disableOriginalConstructor() लेकिन इससे पहले getMock()


3
2018-03-08 02:21





शायद आपको कन्स्ट्रक्टर तर्क के रूप में पास करने के लिए एक स्टब बनाना होगा। फिर आप नकली वस्तुओं की उस श्रृंखला को तोड़ सकते हैं।


1
2017-12-01 22:30



क्या आप कुछ और जानकारी साझा कर सकते हैं - Deep Singh Baweja


वैकल्पिक रूप से आप एक पैरामीटर जोड़ सकते हैं getMock डिफ़ॉल्ट कन्स्ट्रक्टर के कॉलिंग को रोकने के लिए।

$mock = $this->getMock(class_name, methods = array(), args = array(), 
        mockClassName = '', callOriginalConstructor = FALSE);

फिर भी, मुझे लगता है कि डेव 1010 का जवाब अच्छा दिखता है, यह सिर्फ पूर्णता के लिए है।


1
2017-07-21 07:37





PHPUnit को मॉक ऑब्जेक्ट्स पर कन्स्ट्रक्टर को कॉल करने के लिए डिज़ाइन किया गया है; इसे रोकने के लिए आपको या तो चाहिए:

  1. किसी मॉक ऑब्जेक्ट को ऑब्जेक्ट में निर्भरता के रूप में इंजेक्ट करें जिसमें आपको मजाक करने में परेशानी हो रही है
  2. एक टेस्ट क्लास बनाएं जो उस क्लास को बढ़ाती है जिसे आप कॉल करने का प्रयास कर रहे हैं जो माता-पिता कन्स्ट्रक्टर को कॉल नहीं करता है

0
2017-12-08 21:08