آموزش تست کردن برنامه‌های Nodejs با Mocha و Chai و SinonJS - قسمت 2 - کار با Spies و Stubs و Mocks



visibility  
mode_comment   ۰

در این قسمت میخوام مطلب آموزش تست کردن برنامه‌های Nodejs با Mocha و Chai و SinonJS رو ادامه بدم و با استفاده از مثالهای کاربردی نحوه کار با Spies و Stubs و Mocks رو بهتون آموزش بدم.

خب در ابتدا یک دایرکتوری بنام controller به وجود میارم و فایل app.controller.js رو در اون میسازم.

Spies

فرض کنید که کدهای زیر در فایل بالا قرار داده شده است:

همونطور که میبینید یک متد بنام getIndexPage وجود داره که 2 پارامتر ورودی req  و res میگیره و متن Hey رو برای کاربر ارسال میکنه. برای تست کردن این فایل یک فایل در مسیر /tests/controller/app.controller.test.js میسازم و کدهای زیر رو در اون قرار میدم:

همونطور که میبینید فایل app.controller.js رو در این فایل تست وارد کردیم و 2 شئ بنام req و res به وجود میارم و برای res یک متد send قرار دادم. در نهایت متد getIndexPage رو با req و res فراخوانی کردیم.

تا اینجا کار خاصی انجام ندادیم و نمیتونیم با این موارد چیزی رو تست کنیم. ما حالا میتونیم از spy استفاده کنیم و کد مورد نظر رو تست کنیم. شما میتونین assertion هایی رو برای spy تعریف کنید بخاطر اینکه spy یک تابع ساختگی رو در اختیارمون قرار میده و میتونیم با استفاده از اون اجرای تابع رو track کنیم.

همونطور که میبینید sinon رو وارد پروژه کردیم و برای متد send یک spy قرار دادیم. برای به وجود آوردن spy از sinon.spy() استفاده میکنیم. برای اینکه ببینیم spy چه اطلاعاتی رو در اختیارمون قرار میده میتونیم res.send رو در console چاپ کنیم.

برای اجرا کردن تست‌ها از دستور mocha tests/**/*.* استفاده میکنیم و به معنای اینه که همه فایلهایی که در دایرکتوری و sub directory های tests وجود داره رو اجرا کن. خب حالا میخوایم از امکانات spy استفاده کنیم و تست مورد نظرمون رو انجام بدیم. ما میخوایم موارد زیر رو تست کنیم و از کارکرد اونا مطمئن بشیم:

  • ما انتظار داریم که متد res.send یکبار اجرا بشه.
  • ما انتظار داریم که در فراخوانی اول تابع res.send آرگومان Hey رو دریافت کنیم.

برای اینکار بصورت زیر عمل میکنیم:

همونطور که میبینید چک کردیم که ویژگی calledOnce برابر با true باشه و آرگومان اول firstCall برابر با Hey باشه. اگر تست رو اجرا کنیم، خروجی بصورت زیر خواهد بود:

همونطور که میبینید تست مورد نظر با موفقیت انجام میشه و همه چیز همونطوری هست که انتظارشو داریم. حالا مثلا اگر بجای Hey کلمه bla رو قرار بدیم، خواهیم دید که تست fail میشه. بصورت زیر:

در مثال بالا تابعی وجود نداشت و ما یک spy ساختیم و کارهای مورد نظرمون رو انجام دادیم. حالا اگر یک تابع از قبل داشتیم باشیم و بخوایم برای اون spy قرار بدیم و اطلاعات اون رو مثل یک جاسوس (spy) به دست بیاریم، باید چکار کنیم؟ برای اینکار یک تابع ساده رو تعریف میکنیم و با استفاده از متد sinon.spy به اون متصل میشیم. بصورت زیر:

همونطور که میبینید یک متد بنام addUser داریم که یک ورودی name میگیره و اون رو در this.name قرار میده. با استفاده از sinon.spy برای متد addUser مربوط به شئ user یک spy قرار دادیم . حالا user.addUser رو چاپ کردیم تا ببینیم که چه اطلاعاتی رو spy در مورد متد مورد نظر در اختیارمون قرار میده. اگر console رو مشاهده کنید خواهید دید که spy اطلاعات زیادی رو در مورد تابع از قبل تعریف شده نیز در اختیارتون قرار میده.

حالا فرض کنید که ما متد addUser رو فراخوانی کنیم و بعد از اون میخوایم تست کنیم که متد مورد نظر یک بار فراخوانی شده است یا خیر. برای اینکار بصورت زیر عمل میکنیم:

حالا اگر تست بالا رو اجرا کنیم، میبینیم که pass میشه و معلوم میشه که تابع مورد نظر یکبار فراخوانی شده است.

پس تا اینجای کار فهمیدیم که spies یا جاسوس‌ها به چه دردی میخورن و میتونیم هم برای توابع ساختگی و هم توابع از پیش تعریف شده از اونا استفاده کنیم. با استفاده از spy ها میتونین اطلاعات مفیدی رو در مورد نحوه اجرا شدن توابع به دست بیارید و کدهاتون رو از جنبه‌های مختلف تست کنید. استفاده از spies در sinon خیلی ساده هست و بیشتر ویژگی‌ها بر پایه اون ساخته شده‌اند. spy ها یک نقطه شروع خوب برای کار با SinonJS هستند.

Stubs

Stub ها خیلی عالی هستند. بخاطر اینکه همه ویژگی‌های مربوط به Spy ها رو دارند ولی برخلاف spy کل تابع رو جایگزین میکنند. Stubs ها در حالتهای زیر خیلی کاربردی هستند:

  • فراخوانی توابع external که باعث آهسته شدن تست میشن (مانند درخواست‌های HTTP و ارتباط با Database)
  • شبیه‌سازی حالت‌های مختلف برای یک قطعه کد (مثلا اگر یک ارور به وجود بیاد چه اتفاقی میوفته و یا اینکه اگر موفقیت‌آمیز باشه چی بشه)

در فایل app.controller.js موجود در دایرکتوری controllers، متد getIndexPage رو بصورت زیر تغییر میدیم:

همونطور که میبینید در این متد چک شده که کاربر login هست یا خیر و اگر login باشه Hey و در غیر اینصورت متن مورد نظر به کاربر نشون داده میشه و به اون میگه باید در سایت Login بکنه.

isLoggedIn در این حالت یک متد هست که بررسی میکنه که کاربر فعلی Login هست یا خیر. این متد میتونه با استفاده از JWT Token لاگین بودن رو متوجه بشه و یا مستقیما به Database متصل بشه و Login بودن کاربر رو بررسی کنه. برای ما فرقی نمیکنه که ساختار این متد چی هست و به چه روشی این کار رو انجام میده. ما فرض میکنیم که این متد کارهای زیادی رو انجام میده و مدت زمان زیادی هم طول میکشه و اگر کاربر Login باشه true و در غیر اینصورت false رو برمی‌گردونه.

در فایل test کدهای زیر رو جایگزین کدهای قبلی بکنید:

همونطور که میبینید در خط 16 یک stub برای متد isLoggedIn مربوط به شئ user به وجود آوردیم و کاری کردیم که همیشه مقدار true رو برگشت بده. Stub ساخته شده جایگزین متد isLoggedIn میشه و ما میتونیم سناریوی Login بودن کاربر رو تست کنیم. در حالتی که کاربر Login هست باید متن Hey به اون نشون داده بشه. حالا اگر تست‌ها رو مجددا اجرا کنیم، خواهیم دید که pass خواهند شد.

همچنین میتونین Login نبودن کاربر رو نیز تست کنیم. برای اینکار بصورت زیر عمل میکنیم:

اونجاهایی که ... قرار داده شده یعنی همون کدهای قبلی رو قرار بدین. مثال بالا یک کار خیلی ساده هست و شما میتونین کارهای پیشرفته‌تری رو با Stub ها انجام بدین. برای مطالعه مستندات Stubs میتونین بر روی این لینک کلیک کنید.

Mocks

با استفاده از Mocks ما میتونیم مشخص کنیم که چیزها چطوری باید کار کنند و با استفاده از mock.verify() میتونین مطمئن بشید که همونطور که میخواید کار میکنه یا خیر. با اینکار کدها کمتر و خواناتر میشن. با استفاده از تست‌هایی که قبلا نوشتیم ما میتونیم:

  • میتونیم یک mock برای شئ res به وجود بیاریم.
  • میخوایم متد send با آرگومان Hey یکبار فراخوانی بشه.
  • در آخر متد mock.verify() رو فراخوانی میکنیم.

برای اینکار بصورت زیر عمل میکنیم:

همونطور که میبینید در خط 29 mock رو به وجود آورده و چیزی که از اون انتظار داریم رو در خط 31 مشخص کردیم و در نهایت در خط 37 متد verify رو برای تست اون فراخوانی کردیم. اگر دستور mocha test/**/*.* رو مجددا اجرا کنیم، خواهیم دید که تست pass خواهد شد.

نتیجه‌گیری

در این قسمت در مورد کار با Spies و Stubs و Mocks توضیحاتی رو در اختیارتون قرار دادیم و با استفاده از مثالهای ساده کاربرد اونا رو بهتون یاد دادیم.

در قسمت بعد در مورد تست کردن کدهای Async توضیح میدم و یاد میگیریم که چطور با اونا کار کنیم.

متخصص جاوا اسکریپت
با جاوا اسکریپت جادوگری کنید! آیا می دونید با زبان جاوااسکریپت می تونید، برای فرانت اند و بک اند وبسایت ها برنامه نویسی کنید؟ همینطور اپلیکیشن دسکتاپ و موبایل بسازید؟ اگر دوست داری اینکارها رو انجام بدی و React, ElectronJS, ReactNative, NodeJS,MongoDB و ... رو تو یه دوره یاد بگیری، متخصص جاوااسکریپت سون لرن رو حتما ببین : متخصص جاوا اسکریپت arrow_back
7Learn Experts
comment دیدگاه کاربران

add_circle ارسال دیدگاه

خوشحال میشیم دیدگاه و یا تجربیات خودتون رو با ما در میون بذارید :