लारवेल अनुप्रयोगों के साथ काम करते समय, ऐसे परिदृश्यों का सामना करना आम बात है जहां एक कमांड को एक महंगा कार्य करने की आवश्यकता होती है। मुख्य प्रक्रिया को अवरुद्ध करने से बचने के लिए, आप कार्य को किसी ऐसे कार्य पर लोड करने का निर्णय ले सकते हैं जिसे कतार द्वारा संसाधित किया जा सकता है।
आइए एक उदाहरण पर चलते हैं। कमांड ऐप की कल्पना करें: आयात-उपयोगकर्ताओं को एक बड़ी सीएसवी फ़ाइल पढ़ने और प्रत्येक प्रविष्टि के लिए एक उपयोगकर्ता बनाने की आवश्यकता है। यहां कमांड कुछ इस तरह दिख सकती है:
/* ImportUsersCommand.php */ namespace App\Console\Commands; /*...*/ class ImportUsersCommand extends Command { protected $signature = 'app:import-users'; public function handle() { dispatch(new ImportUsersJob()); $this->line('Users imported successfully.'); $this->line('There are: ' . User::count(). ' Users.'); } }
इस उदाहरण में, कमांड फ़ाइल को पढ़ने और उपयोगकर्ताओं के निर्माण को संभालने के लिए एक कार्य भेजता है। यहां बताया गया है कि ImpactUsersJob.php कैसा दिखेगा:
/* ImportUsersJob.php */ namespace App\Jobs; /*...*/ class ImportUsersJob implements ShouldQueue { public function handle(FileReader $reader): void { foreach($reader->read('users.csv') as $data) { User::create([ 'name' => $data['name'], 'email' => $data['email'], ]); } } }
इस सुविधा का परीक्षण करते समय, कमांड के लिए एक विशिष्ट परीक्षण इस तरह दिख सकता है:
/* ImportUsersCommandTest.php */ namespace Tests\Feature; /*...*/ class ImportUsersCommandTest extends TestCase { use RefreshDatabase; public function test_it_processes_the_file(): void { Storage::fake('local')->put('users.csv', "..."); $this->artisan('app:import-users') ->expectsOutput('Users imported successfully.') ->expectsOutput('There are: 10 Users.') ->assertSuccessful(); $this->assertDatabaseCount('users', 10); } }
पहली नज़र में, यह परीक्षण पूरी तरह से काम करता प्रतीत होता है। परीक्षण सूट चलाने से एक सफल परिणाम दिखता है:
हालाँकि, जब आप वास्तविक वातावरण में ऐप:इम्पोर्ट-यूजर्स कमांड चलाते हैं, तो आपको एक अप्रत्याशित परिणाम मिल सकता है:
जैसा कि आप देख सकते हैं, कमांड आउटपुट इंगित करता है कि डेटाबेस में 0 उपयोगकर्ता हैं। तो, ऐसा क्यों होता है?
कारण यह है कि कार्य को एक कतार में भेज दिया जाता है, इसलिए यह कमांड निष्पादन के साथ समकालिक रूप से नहीं चलता है। उपयोगकर्ता तभी बनाए जाएंगे जब कतार बाद में कार्य संसाधित करेगी।
परीक्षण सूट डिफ़ॉल्ट रूप से सिंक कतार ड्राइवर का उपयोग करता है, जिसका अर्थ है कि परीक्षण के दौरान नौकरियों को समकालिक रूप से संसाधित किया जाता है। परिणामस्वरूप, कार्य तुरंत चलता है, जिससे यह विचार आता है कि सब कुछ अपेक्षा के अनुरूप काम करता है।
हालांकि यह व्यवहार परीक्षण परिवेश में स्वीकार्य है, यह पहचानना महत्वपूर्ण है कि वास्तविक दुनिया के परिणाम आपके उत्पादन परिवेश में QUEUE_CONNECTION कॉन्फ़िगरेशन पर निर्भर करते हैं। और आपकी परियोजना आवश्यकताओं को देखते हुए, आप जान सकते हैं कि कार्य को एक एसिंक कतार में संसाधित किया जाएगा।
एक बार जब आप इस अंतर से अवगत हो जाते हैं, तो आप "झूठी सकारात्मकता" से बचने के लिए अपने परीक्षणों में सुधार करना चाहेंगे।
सबसे पहले, यह सत्यापित करना महत्वपूर्ण है कि कमांड वास्तव में कार्य भेजता है, भले ही कार्य समकालिक रूप से संसाधित हो या अतुल्यकालिक रूप से। इसका परीक्षण करने का तरीका यहां बताया गया है:
/* ImportUsersCommandTest.php */ namespace Tests\Feature; /*...*/ class ImportUsersCommandTest extends TestCase { public function test_it_dispatches_the_job(): void { Queue:fake(); $this->artisan('app:import-users') ->expectsOutput('Process has been queued.') ->assertSuccessful(); Queue::assertPushed(ImportUsersJob::class); } }
एक बार जब आप पुष्टि कर लेते हैं कि नौकरी भेज दी गई है, तो आप एक अलग परीक्षण में नौकरी द्वारा किए गए वास्तविक कार्य का परीक्षण कर सकते हैं। यहां बताया गया है कि आप नौकरी के लिए परीक्षा की संरचना कैसे कर सकते हैं:
/* ImportUsersJobTest.php */ namespace Tests\Feature; /*...*/ class ImportUsersJobTest extends TestCase { use refreshDatabase; public function test_it_processes_the_file() { Storage::fake('local')->put('users.csv', "..."); app()->call([new ImportUsersJob(), 'handle']); $this->assertDatabaseCount('users', 10); } }
यह सुनिश्चित करता है कि कार्य आवश्यक कार्य करता है, भले ही इसे कतार द्वारा संसाधित किया गया हो या सिंक्रोनाइज़ किया गया हो।
जैसा कि वास्तविक जीवन में होता है, सीमांत मामले घटित हो सकते हैं और आपको इनके लिए तैयार रहना चाहिए।
लारवेल की कतार प्रणाली, आपके श्रमिक कॉन्फ़िगरेशन के अनुसार, अपवाद होने पर नौकरियों का पुनः प्रयास करेगी, और यदि पुनः प्रयास पार हो जाते हैं, तो कार्य को विफल के रूप में चिह्नित किया जाएगा।
तो, यदि फ़ाइल मौजूद नहीं है तो क्या होगा? आपको इनपुट को सत्यापित करके और आवश्यक होने पर अपवाद फेंककर ऐसे किनारे के मामलों को संभालने की आवश्यकता है।
यहां बताया गया है कि आप अपनी नौकरी में इसे कैसे संभाल सकते हैं:
/* ImportUsersJobTest.php */ namespace App\Jobs; /*...*/ class ImportUsersJob implements ShouldQueue { use Queueable; public function handle(FileReader $reader): void { if(!Storage::disk('local')->exists('users.csv')){ throw new Exception('The users.csv file doesn\'t exist.') } foreach($reader->read('users.csv') as $data) { User::create([ 'name' => $data['name'], 'email' => $data['email'], ]); } } }
यहां बताया गया है कि आप इस परिदृश्य का परीक्षण कैसे करेंगे:
/* ImportUsersJobTest.php */ namespace Tests\Feature; /*...*/ class ImportUsersJobTest extends TestCase { use refreshDatabase; /*...*/ public function test_it_fails_when_file_doesnt_exist(): void { Storage::fake('local'); $this->expectException(Exception::class); $this->expectExceptionMessage('The users.csv file doesn\'t exist.'); dispatch(new ImportUsersJob()); } }
यह दृष्टिकोण सुनिश्चित करता है कि आपके परीक्षण अधिक सटीक रूप से दर्शाते हैं कि वास्तविक दुनिया में नौकरियों को कैसे संसाधित किया जाएगा।
वही रणनीति तब लागू की जा सकती है जब कोई नियंत्रक किसी कार्य को कतार में भेजता है या जहां कोई ईवेंट श्रोता कतारबद्ध होता है।
हमेशा की तरह, अपने प्रोजेक्ट और टीम के अनुरूप इन प्रथाओं को समायोजित करें।
मुझे आपके विचार सुनना अच्छा लगेगा!
अस्वीकरण: उपलब्ध कराए गए सभी संसाधन आंशिक रूप से इंटरनेट से हैं। यदि आपके कॉपीराइट या अन्य अधिकारों और हितों का कोई उल्लंघन होता है, तो कृपया विस्तृत कारण बताएं और कॉपीराइट या अधिकारों और हितों का प्रमाण प्रदान करें और फिर इसे ईमेल पर भेजें: [email protected] हम इसे आपके लिए यथाशीघ्र संभालेंगे।
Copyright© 2022 湘ICP备2022001581号-3