2016-08-31 6 views
14

हमारे पास कुछ विरासत लार्वेल परियोजनाएं हैं जो कक्षाओं में facades का उपयोग करती हैं।इंटीग्रेशन टेस्ट मैक इंजेक्शनिंग बनाम facades बनाम

use Cache; 

LegacyClass 
{ 
    public function cacheFunctionOne() 
    { 
     $result = Cache::someFunction('parameter'); 

     // logic to manipulate result 

     return $result; 
    } 

    public function cacheFunctionTwo() 
    { 
     $result = Cache::someFunction('parameter'); 

     // different logic to manipulate result 

     return $result; 
    } 
} 

हमारे अधिक हाल ही में परियोजनाओं अंतर्निहित laravel कक्षाएं कि अग्रभाग के रूप में किया गया है hinted at by Taylor Otwell himself प्रतिनिधित्व की निर्भरता इंजेक्शन का उपयोग करें। (हम प्रत्येक वर्ग के लिए निर्माता इंजेक्शन का उपयोग करें, लेकिन उदाहरण कम रखने, यहाँ मैं विधि इंजेक्शन का उपयोग करें और का उपयोग एक भी वर्ग के लिए।)

use Illuminate\Cache\Repository as Cache; 

ModernClass 
{ 
    public function cacheFunctionOne(Cache $cache) 
    { 
     $result = $cache->someFunction('parameter'); 

     // logic to manipulate result 

     return $result; 
    } 

    public function cacheFunctionTwo(Cache $cache) 
    { 
     $result = $cache->someFunction('parameter'); 

     // different logic to manipulate result 

     return $result; 
    } 
} 

मैं अग्रभाग can be mocked

public function testExample() 
{ 
    Cache::shouldReceive('get') 
       ->once() 
       ->with('key') 
       ->andReturn('value'); 

    $this->visit('/users')->see('value'); 
} 

कौन सा के लिए अच्छी तरह से काम करता है इकाई परीक्षण। जिस समस्या को मैं समझने की कोशिश कर रहा हूं वह यह है कि यदि इन facades 'वैश्विक स्तर पर' मजाक कर रहे हैं।

उदाहरण के लिए, की सुविधा देता है की कल्पना मैं एक एकीकरण परीक्षण लिख रहा हूँ (कुछ परस्पर वर्गों का परीक्षण सेवाओं मजाक करते हुए - नहीं समाप्त लाइव सेवाओं का उपयोग कर परीक्षण समाप्त करने के लिए) जो कुछ बिंदु पर, दो अलग-अलग वर्गों जो एक ही मुखौटा शामिल कार्यान्वित जो एक ही पैरामीटर के साथ एक ही विधि को कॉल करता है।

इन कक्षाओं में बुलाया जा रहा है के बीच में, कुछ जटिल कार्यक्षमता में परिवर्तन है कि डेटा क्या एक ही पैरामीटर का उपयोग कर कि अग्रभाग विधि द्वारा दिया जाता है। *

$modernClass->cacheFunctionOne($cache); // easily mocked 

// logic that changes data returned by laravel Cache object function 'someFunction' 

$modernClass->cacheFunctionTwo($cache); // easily mocked with a different mock 

हमारे आधुनिक कक्षाओं का परीक्षण करने के लिए आसान कर रहे हैं क्योंकि अंतर्निहित वर्ग मुखौटा का प्रतिनिधित्व प्रत्येक वर्ग में इंजेक्शन दिया जाता है (इस उदाहरण में, प्रत्येक विधि)। इसका मतलब है कि मैं अलग-अलग परिणामों को नकल करने के लिए दो अलग-अलग झटके बना सकता हूं और उन्हें प्रत्येक वर्ग (विधि) में इंजेक्ट कर सकता हूं।

$legacyClass->cacheFunctionOne(); 

// logic that changes data returned by laravel Cache object function 'someFunction' 

$legacyClass->cacheFunctionTwo(); 

विरासत प्रणालियों हालांकि में, यह कि मज़ाक उड़ाया मुखौटा 'वैश्विक' है ताकि जब मुखौटा प्रत्येक वर्ग में चलाया जाता है, ठीक उसी मूल्य दिया जाता है प्रतीत होता है।

क्या मैं यह सोचने में सही हूं?

* मुझे लगता है कि यह उदाहरण कोड आर्किटेक्चर और परीक्षण बिंदु से पूरी तरह से अनावश्यक प्रतीत हो सकता है, लेकिन मैं जो कुछ पूछ रहा हूं उसके कुछ प्रकार के 'सरल' उदाहरण को आजमाने और देने के लिए सभी वास्तविक कार्यक्षमताओं को अलग कर रहा हूं।

उत्तर

6

निर्भरता इंजेक्शन बनाम Facades

निर्भरता इंजेक्शन का बड़ा लाभ यह है कि कोड एक बहुत अधिक परीक्षण योग्य एक बार आप के बजाय तरीकों में निर्भरता इंजेक्शन लगाने instantiating/उन्हें विधि के अंदर हार्डकोड शुरू हो जाता है। ऐसा इसलिए है क्योंकि आप अंदरूनी इकाई परीक्षणों से निर्भरताओं में गुजर सकते हैं और वे कोड के माध्यम से प्रचार करेंगे।

देखें: http://slashnode.com/dependency-injection/

निर्भरता इंजेक्शन Facades के एकदम विपरीत है। फेकाडे स्थिर वैश्विक वर्ग हैं, PHP भाषा स्थिर वर्गों पर स्थिर कार्यों को ओवरराइट या प्रतिस्थापित करने की अनुमति नहीं देती है। लार्वाले मुखौटे नकली कार्यक्षमता प्रदान करने के लिए मॉकरी का उपयोग करते हैं और वे उपर्युक्त तथ्यों से सीमित हैं।

एकीकरण परीक्षण के लिए समस्या आ सकती है जहां आप एक गैर-नकली कैश से डेटा पुनर्प्राप्त करने की उम्मीद कर रहे हैं, लेकिन एक बार जब आप फेकाडे :: कंधे() का उपयोग करते हैं तो फेकाडे :: get() को मॉक कैश द्वारा ओवरराइड किया जाएगा। विपरीत भी सही है। नतीजतन, फेकाडे अनुचित हैं जहां आप मॉक किए गए और अनमॉक किए गए डेटा के लिए इंटरलविंग कॉल कर रहे हैं।

आपको आवश्यक डेटा सेट के साथ अपने कोड का परीक्षण करने के लिए, सबसे अच्छा अभ्यास DI का उपयोग करने के लिए आपके विरासत कोड को दोबारा करना होगा।

एकता टेस्ट

आसान विधि

एक वैकल्पिक अपने एकीकरण परीक्षण की शुरुआत में उम्मीदों के साथ कई फसाड :: shouldReceive() कॉल करने के लिए है। यह सुनिश्चित करना कि आपके पास एकीकरण परीक्षण में किए गए प्रत्येक कॉल के लिए सही क्रम में अपेक्षाओं की सही संख्याएं हों। यह संभवतः आपके मौजूदा कोडबेस को दिए गए परीक्षण लिखने का तेज़ तरीका होगा।

कठिन विधि

निर्भरता इंजेक्शन जबकि सबसे अच्छा अभ्यास प्रोग्रामिंग है। यह बहुत अच्छा हो सकता है कि आपके कोडबेस में इतनी विरासत कक्षाएं हैं कि यह रिफैक्टर के लिए अविश्वसनीय समय लेगी। इस मामले में, यह फिक्स्चर के साथ एक परीक्षण डेटाबेस का उपयोग कर एंड-टू-एंड एकीकरण परीक्षण पर विचार करने योग्य हो सकता है।

परिशिष्ट:

+0

के लिए धन्यवाद विस्तृत स्पष्टीकरण। – myol

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