2015-04-05 18 views
10

मैं Laravel 5 में मेरी नियंत्रकों का परीक्षण इकाई के लिए कोशिश कर रहा हूँ, लेकिन यह चारों ओर मेरे सिर लपेटकर गंभीर मुद्दों की है। ऐसा लगता है कि अगर मैं वास्तव में पृथक इकाई परीक्षण करना चाहता हूं तो निर्भरता इंजेक्शन वाले समकक्षों के लिए मुझे महान शॉर्ट-हाथ फ़ंक्शंस और स्थैतिक कक्षाओं का व्यापार करना होगा।Laravel 5 अलग नियंत्रक परीक्षण

सबसे पहले, मैं "इकाई परीक्षण" के रूप में documentation में क्या देखते हैं, मेरे लिए इकाई परीक्षण नहीं है। यह कार्यात्मक परीक्षण की तरह लगता है। मैं एक नियंत्रक फ़ंक्शन को अलग नहीं कर सकता, क्योंकि मुझे पूरे ढांचे के माध्यम से जाना होगा, और यदि मेरे पास मेरे डेटाबेस के साथ कोई कोड इंटरैक्ट कर रहा है तो मुझे वास्तव में मेरे डेटाबेस को बीज करने की आवश्यकता होगी।

तो, बारी में, मैं अपने नियंत्रक ढांचे के पृथक परीक्षण करना चाहते हैं। हालांकि यह काफी मुश्किल साबित हो रहा है। इस उदाहरण समारोह में

आइए नज़र (मैं प्रश्न के लिए इस समारोह के कुछ भागों बाहर रखा है):

public function postLogin(\Illuminate\Http\Request $request) 
{ 
    $this->validate($request, [ 
     'email' => 'required|email', 'password' => 'required', 
    ]); 

    $credentials = $request->only('email', 'password'); 

    if (Auth::attempt($credentials, $request->has('remember'))) 
    { 
     return redirect()->intended($this->redirectPath()); 
    } 
} 

अब, समस्या अंतिम लाइनों में पैदा होती है। निश्चित रूप से, मैं अनुरोध उदाहरण को नकल कर सकता हूं जो फ़ंक्शन पर भेजा गया है, यह कोई मुद्दा नहीं है। लेकिन मैं ऑथ क्लास या रीडायरेक्ट फ़ंक्शन का नकल कैसे करूँगा? मैं इस तरह निर्भरता इंजेक्शन के साथ मेरी कक्षा/समारोह को फिर से लिखने की जरूरत है:

private $auth; 
private $redirector; 

public function __construct(Guard $auth, \Illuminate\Routing\Redirector $redirector) 
{ 
    $this->auth = $auth; 
    $this->redirector = $redirector; 
} 

public function postLogin(\Illuminate\Http\Request $request) 
{ 
    $this->validate($request, [ 
     'email' => 'required|email', 'password' => 'required', 
    ]); 

    $credentials = $request->only('email', 'password'); 

    if ($this->auth->attempt($credentials, $request->has('remember'))) 
    { 
     return $this->redirector->intended($this->redirectPath()); 
    } 
} 

और मैं एक जटिल इकाई परीक्षण के साथ खत्म, mocks से भरा:

public function testPostLoginWithCorrectCredentials() 
{ 
    $guardMock = \Mockery::mock('\Illuminate\Contracts\Auth\Guard', function($mock){ 
     $mock->shouldReceive('attempt')->with(['email' => 'test', 'password' => 'test'], false)->andReturn(true); 
    }); 

    $redirectorMock = \Mockery::mock('\Illuminate\Routing\Redirector', function($mock){ 
     $mock->shouldReceive('intended')->andReturn('/somePath'); 
    }); 

    $requestMock = \Mockery::mock('\Illuminate\Http\Request', function($mock){ 
     $mock->shouldReceive('only')->with('email', 'password')->andReturn(['email' => 'test', 'password' => 'test']); 
     $mock->shouldReceive('has')->with('remember')->andReturn(false); 
    }); 

    $object = new AuthController($guardMock, $redirectorMock); 
    $this->assertEquals('/somePath', $object->postLogin($requestMock)); 
} 

अब, अगर मैं किसी भी अधिक जटिल था तर्क, उदाहरण के लिए, एक मॉडल का उपयोग करेगा, मुझे निर्भरता भी उस इंजेक्शन को इंजेक्ट करना होगा, और इसे मेरी कक्षा में नकली करना होगा।

मेरे लिए, यह या तो की तरह लगता है, Laravel प्रदान नहीं कर रहा है कि मैं क्या करना चाहते हैं, या मेरे परीक्षण तर्क त्रुटिपूर्ण है। क्या कोई तरीका है कि मैं अपने नियंत्रक कार्यों का परीक्षण कर सकता हूं बिना नियंत्रण नियंत्रण कार्यों और/या मानक लारवेल कक्षाओं को इंजेक्ट करने के लिए, मेरे नियंत्रक में किसी भी तरह से उपलब्ध है?

+1

मुझे व्यक्तिगत रूप से नहीं लगता कि यह केवल नियंत्रक इकाई परीक्षण के लिए बहुत अधिक समझ में आता है।आम तौर पर नियंत्रक का उपयोग केवल चीजों को व्यवस्थित करने और सब कुछ एक साथ लाने के लिए किया जाता है। जिसे कार्यात्मक परीक्षण के साथ अच्छी तरह से परीक्षण किया जा सकता है। अगर मेरे पास तर्क है कि मैं वास्तव में एक नियंत्रक में इकाई परीक्षण (बाकी से अलग से) करना चाहता हूं तो यह अक्सर एक संकेत है कि यह वहां नहीं होना चाहिए बल्कि सेवा/रिपोजिटरी/मॉडल/आदि – lukasgeiter

+0

में नीचे लुका और शिफ्ट विनिमय के साथ सहमत होना चाहिए । एक नियंत्रक की एकमात्र ज़िम्मेदारी अनुरोध लेना, नौकरियों का प्रतिनिधि होना, परिणाम इकट्ठा करना और प्रतिक्रिया के रूप में इसे वापस भेजना है। वहां वास्तविक काम की कोई इकाई नहीं होनी चाहिए, कि आप इकाई परीक्षण करना चाहते हैं, इसलिए यह इकाई के अधीन नहीं है, बल्कि कार्यात्मक परीक्षण है। –

उत्तर

10

आपको इकाई परीक्षण नियंत्रकों की कोशिश नहीं करनी चाहिए। उन्हें HTTP प्रोटोकॉल के माध्यम से कॉल करके कार्यात्मक परीक्षण के लिए डिज़ाइन किया गया है। इस प्रकार नियंत्रकों को डिज़ाइन किया गया है, और लैरावेल कई फ्रेमवर्क दावों को प्रदान करता है जिन्हें आप अपने परीक्षणों में शामिल कर सकते हैं ताकि यह सुनिश्चित किया जा सके कि वे अपेक्षित काम करते हैं।

लेकिन अगर आप इकाई परीक्षण करने के लिए आवेदन नियंत्रक के भीतर निहित कोड चाहते हैं, तो आप वास्तव में Commands उपयोग करने पर विचार करना चाहिए।

कमांड का उपयोग करके आप किसी कक्षा के लिए अपने नियंत्रक से आवेदन तर्क extracte की अनुमति देता है। इसके बाद आप उम्मीद कर सकते हैं कि आप परिणाम प्राप्त करने के लिए कक्षा/कमांड का परीक्षण करें।

आप बस नियंत्रक से कमांड को कॉल कर सकते हैं।

In fact the Laravel documentation tells you this:

हम एक नियंत्रक विधि के अंदर इस तर्क के सभी डाल सकता है; हालांकि, इसके कई नुकसान हैं ... कमांड को यूनिट-टेस्ट करना अधिक कठिन है क्योंकि हमें एक स्टब HTTP अनुरोध भी उत्पन्न करना होगा और खरीद पॉडकास्ट तर्क का परीक्षण करने के लिए एप्लिकेशन को पूर्ण अनुरोध करना होगा।

+0

लेकिन यूनिट परीक्षण के बारे में क्या है जो अलग-अलग एप्लिकेशन कोड है? यह सवाल का जवाब नहीं देता है अगर मैं गलत तरीके से यूनिट परीक्षण के बारे में जा रहा हूं, बस मुझे अपने नियंत्रक का परीक्षण नहीं करना चाहिए। समस्या यह है कि, मुझे अभी भी लार्वेल सहायक कार्यों आदि का मज़ाक उड़ाने के लिए सौदा करना होगा, जो ईमानदार होने का दर्द है। –

+0

हाँ - तो आपको आम तौर पर * कार्यात्मक * पर अपने आवेदन तर्क का परीक्षण करना चाहिए। आप कमांड चलाते हैं, और परीक्षण करते हैं कि आप अपेक्षित आउटपुट प्राप्त करते हैं। मैंने कभी भी अपना डेटाबेस मॉक नहीं किया - यह बहुत अधिक समय है - मैं सिर्फ https://github.com/laracasts/TestDummy और परीक्षण के लिए SQLite डेटाबेस का उपयोग करता हूं। यह बहुत तेजी से, परीक्षण लिखने में आसान है, और आपको कुछ भी नकल करने की आवश्यकता नहीं है ... – Laurence

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