2013-07-02 16 views
7

साथ काम नहीं करते मैं creating मॉडल इवेंट के साथ Laravel 4 में एक मॉडल साइड सत्यापन का निर्माण:Laravel 4 मॉडल घटनाक्रम PHPUnit

class User extends Eloquent { 

    public function isValid() 
    { 
     return Validator::make($this->toArray(), array('name' => 'required'))->passes(); 
    } 

    public static function boot() 
    { 
     parent::boot(); 

     static::creating(function($user) 
     { 
      echo "Hello"; 
      if (!$user->isValid()) return false; 
     }); 
    } 
} 

यह अच्छी तरह से काम करता है, लेकिन मैं PHPUnit के साथ समस्या है। दो निम्नलिखित परीक्षणों बिल्कुल एक जैसे हैं, लेकिन पहले एक पास juste:

class UserTest extends TestCase { 

    public function testSaveUserWithoutName() 
    { 
     $count = User::all()->count(); 

     $user = new User; 
     $saving = $user->save(); 

     assertFalse($saving);      // pass 
     assertEquals($count, User::all()->count()); // pass 
    } 

    public function testSaveUserWithoutNameBis() 
    { 
     $count = User::all()->count(); 

     $user = new User; 
     $saving = $user->save(); 

     assertFalse($saving);      // fail 
     assertEquals($count, User::all()->count()); // fail, the user is created 
    } 
} 

अगर मैं एक उपयोगकर्ता एक ही परीक्षा में दो बार बनाने का प्रयास करें, यह काम करता है, लेकिन यह करता है, तो बंधन घटना केवल में मौजूद है की तरह है मेरी टेस्ट क्लास का पहला टेस्ट। पहले परीक्षण निष्पादन के दौरान echo "Hello"; केवल एक बार मुद्रित किया जाता है।

मैं अपने प्रश्न के मामले को सरल बना देता हूं लेकिन आप समस्या देख सकते हैं: मैं विभिन्न यूनिट परीक्षणों में कई सत्यापन नियमों का परीक्षण नहीं कर सकता। मैं घंटों से लगभग हर चीज की कोशिश करता हूं लेकिन अब मैं खिड़कियों से बाहर निकलने के करीब हूं! कोई उपाय ?

+2

पढ़ें https://github.com/laravel/ढांचे/मुद्दों/1181 – crynobone

+2

धन्यवाद। अंत में, मॉडल घटनाक्रम आसानी से परीक्षण योग्य नहीं हैं। मैं उस चाल के साथ अपनी समस्या का समाधान करता हूं: मैं अपने 'setUp()' विधि में 'उपयोगकर्ता :: बूट() 'को कॉल करता हूं। –

+1

मैं 'उपयोगकर्ता :: निरीक्षण (नया उपयोगकर्ता ऑब्सर्वर) 'का उपयोग करना पसंद करता हूं, इस तरह आप' UserObserver' का परीक्षण स्वयं कर सकते हैं। – crynobone

उत्तर

3

यह समस्या गीथूब में अच्छी तरह से प्रलेखित है। उपर्युक्त टिप्पणियां देखें जो इसे आगे बताती हैं।

मैंने परीक्षण के दौरान सभी मॉडल घटनाओं को स्वचालित रूप से रीसेट करने के लिए गीथब में 'समाधान' में से एक को संशोधित किया है। अपनी TestCase.php फ़ाइल में निम्न जोड़ें।

एप्लिकेशन/परीक्षण/TestCase.php

public function setUp() 
{ 
    parent::setUp(); 
    $this->resetEvents(); 
} 


private function resetEvents() 
{ 
    // Get all models in the Model directory 
    $pathToModels = '/app/models'; // <- Change this to your model directory 
    $files = File::files($pathToModels); 

    // Remove the directory name and the .php from the filename 
    $files = str_replace($pathToModels.'/', '', $files); 
    $files = str_replace('.php', '', $files); 

    // Remove "BaseModel" as we dont want to boot that moodel 
    if(($key = array_search('BaseModel', $files)) !== false) { 
     unset($files[$key]); 
    } 

    // Reset each model event listeners. 
    foreach ($files as $model) { 

     // Flush any existing listeners. 
     call_user_func(array($model, 'flushEventListeners')); 

     // Reregister them. 
     call_user_func(array($model, 'boot')); 
    } 
} 
+0

यह मेरी मूल चाल से अधिक सामान्य तरीके से मेरी समस्या हल करता है (केवल प्रत्येक मॉडल के लिए 'उपयोगकर्ता :: बूट() 'जैसी एक पंक्ति जोड़ें) लेकिन यह मुझे दो कारणों से परेशान करने देता है: यह मेरे अंदर अजीब कोड का एक गुच्छा जोड़ता है टेस्टकेस क्लास और यह प्रत्येक टेस्ट से पहले फाइलों को पार करती है (जो प्रदर्शन समस्याओं का कारण बन सकती है) ... –

+0

मॉडल मॉडल को पहले विस्तारित करता है या नहीं, कभी-कभी उन्हें फ्लशइवेंट लिस्टेनर्स विधि नहीं हो सकती है। – Benubird

0

मैं उपनिर्देशिका में अपने मॉडल तो मैं @TheShiftExchange कोड संपादित किया है एक सा

//Get all models in the Model directory 
$pathToModels = '/path/to/app/models'; 
$files = File::allFiles($pathToModels); 

foreach ($files as $file) { 
    $fileName = $file->getFileName(); 
    if (!ends_with($fileName, 'Search.php') && !starts_with($fileName, 'Base')) { 
     $model = str_replace('.php', '', $fileName); 
     // Flush any existing listeners. 
     call_user_func(array($model, 'flushEventListeners')); 
     // Re-register them. 
     call_user_func(array($model, 'boot')); 
    } 
} 
संबंधित मुद्दे