از طریق منوی جستجو مطلب مورد نظر خود در وبلاگ را به سرعت پیدا کنید
استفاده از Mocks برای تست در جاوا اسکریپت با JestJest یک چارچوب تست منبع باز محبوب برای جاوا اسکریپت است. ما میتوانیم از Jest برای ایجاد mock در آزمایش خود استفاده کنیم – اشیایی که جایگزین اشیاء واقعی در کد ما در هنگام آزمایش میشوند. در سری قبلی ما روی تکنیک های تست واحد با استفاده از Sinon.js، روش استفاده از Sinon را توضیح دادیم.
سرفصلهای مطلب
معرفی
Jest یک چارچوب تست منبع باز و محبوب برای جاوا اسکریپت است. ما میتوانیم از Jest برای ایجاد mock در آزمایش خود استفاده کنیم – اشیایی که جایگزین اشیاء واقعی در کد ما در هنگام آزمایش میشوند.
در سری قبلی ما روی تکنیکهای تست واحد با استفاده از Sinon.js، توضیح دادیم که چگونه میتوانیم از Sinon.js برای خرد کردن، جاسوسی و تمسخر برنامههای Node.js استفاده کنیم – بهویژه تماسهای HTTP.
در این مجموعه قصد داریم با استفاده از تکنیک های تست واحد در Node.js را پوشش دهیم شوخی. Jest توسط فیس بوک ایجاد شده است و به خوبی با بسیاری از کتابخانه ها و چارچوب های جاوا اسکریپت مانند React، Angular و Vue ادغام می شود. تمرکز خاصی دارد روی سادگی و عملکرد
در این مقاله به بررسی تملک ها می پردازیم سپس تمرکز کنید روی چگونه میتوانیم Jest را برای یک برنامه Node.js راهاندازی کنیم تا در آزمایش خود یک تماس HTTP را مسخره کنیم. سپس روش استفاده از Jest و Sinon را برای ساختن ماک برای برنامه های خود مقایسه خواهیم کرد.
Mocks چیست؟
در تست واحد، ماکها این قابلیت را به ما میدهند که عملکرد ارائهشده توسط یک وابستگی و وسیلهای را برای مشاهده روش تعامل کد ما با وابستگی فراهم کنیم. Mock ها به ویژه زمانی مفید هستند که گنجاندن یک وابستگی مستقیماً در تست های ما گران یا غیرعملی باشد، به عنوان مثال، در مواردی که کد شما در حال برقراری تماس HTTP با یک API یا تعامل با لایه پایگاه داده است.
ترجیحاً پاسخهای مربوط به این وابستگیها را حذف کنید، در حالی که مطمئن شوید که در صورت لزوم فراخوانی میشوند. اینجاست که مسخره کردن به کار می آید.
حالا ببینیم چگونه میتوانیم از Jest برای ایجاد mock در Node.js استفاده کنیم.
راه اندازی Jest در یک برنامه Node.js
در این آموزش، ما یک برنامه Node.js راه اندازی می کنیم که تماس های HTTP را با یک JSON API حاوی عکس های یک آلبوم برقرار می کند. Jest برای تمسخر تماسهای API در آزمایشهای ما استفاده خواهد شد.
ابتدا، بیایید دایرکتوری را ایجاد کنیم که فایل های ما در آن قرار می گیرند و به آن منتقل می شوند:
$ mkdir PhotoAlbumJest && cd PhotoAlbumJest
سپس، بیایید پروژه Node را با تنظیمات پیش فرض مقداردهی اولیه کنیم:
$ npm init -y
هنگامی که پروژه مقداردهی اولیه شد، سپس اقدام به ایجاد یک می کنیم index.js
فایل در root از دایرکتوری:
$ touch index.js
برای کمک به ما در مورد درخواستهای HTTP، از آن استفاده خواهیم کرد Axios.
راه اندازی Axios
استفاده خواهیم کرد axios
به عنوان مشتری HTTP ما. Axios یک سرویس گیرنده HTTP سبک وزن و مبتنی بر وعده برای Node.js است که می تواند توسط مرورگرهای وب نیز استفاده شود. این باعث می شود آن را برای مورد استفاده ما مناسب باشد.
بیایید ابتدا آن را نصب کنیم:
$ npm i axios --save
قبل از استفاده axios
، یک فایل به نام ایجاد می کنیم axiosConfig.js
که از طریق آن کلاینت Axios را پیکربندی می کنیم. پیکربندی مشتری به ما امکان می دهد از تنظیمات مشترک در مجموعه ای از درخواست های HTTP استفاده کنیم.
برای مثال، میتوانیم سرصفحههای مجوز را برای مجموعهای از درخواستهای HTTP، یا معمولاً، یک URL پایه که برای همه درخواستهای HTTP استفاده میشود، تنظیم کنیم.
بیایید فایل پیکربندی را ایجاد کنیم:
touch axiosConfig.js
حالا بیایید دسترسی داشته باشیم axios
و URL پایه را پیکربندی کنید:
const axios = require('axios');
const axiosInstance = axios.default.create({
baseURL: 'https://jsonplaceholder.typicode.com/albums'
});
module.exports = axiosInstance;
پس از تنظیم baseURL
، ما صادر کرده ایم axios
به عنوان مثال تا بتوانیم از آن در سراسر برنامه خود استفاده کنیم. استفاده خواهیم کرد www.jsonplaceholder.typicode.com
که یک REST API آنلاین جعلی برای آزمایش و نمونه سازی است.
در index.js
فایلی که قبلا ایجاد کردیم، بیایید تابعی را تعریف کنیم که فهرستی از URLهای عکس را که شناسه آلبوم داده شده را برمی گرداند:
const axios = require('./axiosConfig');
const getPhotosByAlbumId = async (id) => {
const result = await axios.request({
method: 'get',
url: `/${id}/photos؟_limit=3`
});
const { data } = result;
return data;
};
module.exports = getPhotosByAlbumId;
برای ضربه زدن به API ما به سادگی از آن استفاده می کنیم axios.request()
روش ما axios
نمونه، مثال. به نام متد می گذریم که در مورد ما a است get
و url
که به آن استناد خواهیم کرد.
رشته ای که به آن پاس می دهیم url
فیلد به baseURL
از جانب axiosConfig.js
.
حالا بیایید یک تست Jest برای این تابع تنظیم کنیم.
راه اندازی Jest
برای راه اندازی Jest، ابتدا باید Jest را به عنوان یک وابستگی توسعه با استفاده از آن نصب کنیم npm
:
$ npm i jest -D
این -D
flag یک میانبر برای --save-dev
، که به NPM می گوید آن را به عنوان یک وابستگی توسعه ذخیره کند.
سپس اقدام به ایجاد یک فایل پیکربندی برای Jest می کنیم jest.config.js
:
touch jest.config.js
در حال حاضر، در jest.config.js
فایل، دایرکتوری هایی را که تست های ما در آنها قرار می گیرند را تنظیم می کنیم:
module.exports = {
testMatch: (
'<rootDir>/**/__tests__/**/?(*.)(spec|test).js',
'<rootDir>/**/?(*.)(spec|test).js'
),
testEnvironment: 'node',
};
این testMatch
value آرایه ای از الگوهای جهانی است که Jest برای شناسایی فایل های آزمایشی استفاده می کند. در مورد ما، ما مشخص می کنیم که هر فایلی در داخل __tests__
دایرکتوری یا هر جایی از پروژه ما که دارای a .spec.js
یا .test.js
پسوند باید به عنوان یک فایل آزمایشی در نظر گرفته شود.
توجه داشته باشید: در جاوا اسکریپت، دیدن پایان فایل های آزمایشی معمول است .spec.js
. توسعه دهندگان استفاده می کنند “مشخصات” به عنوان مختصر برای “مشخصات”. مفهوم این است که تست ها شامل الزامات عملکردی یا مشخصات برای توابع در حال اجرا هستند.
این testEnvironment
مقدار نشان دهنده محیطی است که Jest در آن اجرا می شود، یعنی چه در Node.js یا در مرورگر. میتوانید درباره سایر گزینههای پیکربندی مجاز بیشتر بخوانید اینجا.
حالا بیایید خودمان را اصلاح کنیم package.json
اسکریپت تست به طوری که از Jest به عنوان اجرای آزمایشی ما استفاده می کند:
"scripts": {
"test": "jest"
},
راه اندازی ما انجام شده است. برای آزمایش اینکه پیکربندی ما کار می کند، یک فایل آزمایشی در آدرس ایجاد کنید root دایرکتوری به نام index.spec.js
:
touch index.spec.js
اکنون، در داخل فایل، بیایید یک تست بنویسیم:
describe('sum of 2 numbers', () => {
it(' 2 + 2 equal 4', () => {
expect(2 + 2).toEqual(4)
});
});
این کد را با دستور زیر اجرا کنید:
$ npm test
شما باید این نتیجه را بگیرید:
PASS ./index.spec.js
sum of 2 numbers
✓ 2 + 2 equal 4 (3ms)
Test Suites: 1 passed, 1 total
Tests: 1 passed, 1 total
Snapshots: 0 total
Time: 0.897s, estimated 1s
Ran all test suites.
با تنظیم صحیح Jest، اکنون می توانیم به نوشتن کد برای تمسخر تماس HTTP خود ادامه دهیم.
تمسخر تماس HTTP با Jest
در index.spec.js
فایل، ما تازه شروع می کنیم، کد قدیمی را حذف می کنیم و یک اسکریپت جدید می نویسیم که تماس HTTP را مسخره می کند:
const axios = require('./axiosConfig');
const getPhotosByAlbumId = require('./index');
jest.mock('./axiosConfig', () => {
return {
baseURL: 'https://jsonplaceholder.typicode.com/albums',
request: jest.fn().mockResolvedValue({
data: (
{
albumId: 3,
id: 101,
title: 'incidunt alias vel enim',
url: 'https://via.placeholder.com/600/e743b',
thumbnailUrl: 'https://via.placeholder.com/150/e743b'
},
{
albumId: 3,
id: 102,
title: 'eaque iste corporis tempora vero distinctio consequuntur nisi nesciunt',
url: 'https://via.placeholder.com/600/a393af',
thumbnailUrl: 'https://via.placeholder.com/150/a393af'
},
{
albumId: 3,
id: 103,
title: 'et eius nisi in ut reprehenderit labore eum',
url: 'https://via.placeholder.com/600/35cedf',
thumbnailUrl: 'https://via.placeholder.com/150/35cedf'
}
)
}),
}
});
اینجا، اول ما import وابستگی های ما با استفاده از require
نحو. از آنجایی که ما نمیخواهیم تماس واقعی با شبکه برقرار کنیم، یک الگوی دستی از خود ایجاد میکنیم axiosConfig
با استفاده از jest.mock()
روش. این jest.mock()
متد مسیر ماژول را به عنوان آرگومان و پیاده سازی اختیاری ماژول را به عنوان a می گیرد پارامتر کارخانه.
برای پارامتر کارخانه، مشخص می کنیم که mock ما، axiosConfig
، باید یک شی متشکل از baseURL
و request()
. این baseUrl
روی URL پایه API تنظیم شده است. این request()
یک تابع ساختگی است که آرایه ای از عکس ها را برمی گرداند.
این request()
تابعی که در اینجا تعریف کردیم جایگزین واقعی می شود axios.request()
تابع. وقتی ما به request()
روش، متد ساختگی ما به جای آن فراخوانی می شود.
آنچه مهم است توجه داشته باشید این است jest.fn()
تابع. جدید را برمی گرداند عملکرد ساختگیو پیاده سازی آن در داخل پرانتز تعریف شده است. کاری که ما از طریق mockResolvedValue()
تابع ارائه یک پیاده سازی جدید برای request()
تابع.
به طور معمول، این کار از طریق mockImplementation()
تابع، هر چند از آنجایی که ما واقعاً فقط آن را برمی گردانیم data
که نتایج ما را نگه می دارد – به جای آن می توانیم از تابع قند استفاده کنیم.
mockResolvedValue()
مثل این هست که mockImplementation(() => Promise.resolve(value))
.
با یک ماکت در جای خود، بیایید جلو برویم و یک تست بنویسیم:
describe('test getPhotosByAlbumId', () => {
afterEach(() => jest.resetAllMocks());
it('fetches photos by album id', async () => {
const photos = await getPhotosByAlbumId(3);
expect(axios.request).toHaveBeenCalled();
expect(axios.request).toHaveBeenCalledWith({ method: 'get', url: '/3/photos؟_limit=3' });
expect(photos.length).toEqual(3);
expect(photos(0).albumId).toEqual(3)
});
});
پس از هر مورد آزمایشی، ما اطمینان حاصل می کنیم که jest.resetAllMocks()
تابع برای بازنشانی وضعیت همه ماک ها فراخوانی می شود.
در مورد آزمایشی ما، ما با getPhotosByAlbumId()
تابع با شناسه از 3
به عنوان استدلال سپس ما ادعاهای خود را بیان می کنیم.
ادعای اول انتظار دارد که axios.request()
متد فراخوانی شد، در حالی که ادعای دوم بررسی می کند که روش با پارامترهای صحیح فراخوانی شده است. همچنین بررسی می کنیم که طول آرایه برگشتی باشد 3
و اینکه اولین شی از آرایه دارای یک است albumId
از 3
.
بیایید تست های جدید خود را با این موارد اجرا کنیم:
npm test
باید نتیجه زیر را بگیریم:
PASS ./index.spec.js
test getPhotosByAlbumId
✓ fetches photos by album id (7ms)
Test Suites: 1 passed, 1 total
Tests: 1 passed, 1 total
Snapshots: 0 total
Time: 0.853s, estimated 1s
Ran all test suites.
با این آشنایی و تجربه جدید، بیایید یک مقایسه سریع از تجربیات تست با Jest و Sinon انجام دهیم، که معمولا برای تمسخر نیز استفاده می شود.
Sinon Mocks vs Jest Mocks
Sinon.js و Jest روشهای متفاوتی برای برخورد با مفهوم تمسخر دارند. در زیر برخی از تفاوت های اصلی ذکر شده است:
- در جست، وقتی فایلهای ساختگی را در یک قرار میدهید، ماژولهای Node.js بهطور خودکار در آزمایشهای شما مسخره میشوند.
__mocks__
پوشه ای که در کنارnode_modules
پوشه به عنوان مثال، اگر شما یک فایل تماس بگیرید__mock__/fs.js
، سپس هر بار کهfs
ماژول در آزمون شما فراخوانی می شود، Jest به طور خودکار از ماک ها استفاده می کند. از طرف دیگر، با Sinon.js باید هر وابستگی را به صورت دستی با استفاده از آن مسخره کنیدsinon.mock()
روش روی هر آزمونی که به آن نیاز دارد - در جست، ما از
jest.fn().mockImplementation()
روشی برای جایگزینی اجرای یک تابع مسخره شده با پاسخ stubbed. یک مثال خوب از این را می توان در مستندات Jest یافت اینجا. در Sinon.js، ما ازmock.expects()
روش رسیدگی به آن - Jest تعداد زیادی روش برای کار با API ساختگی خود و به ویژه با ماژول ها ارائه می دهد. می توانید همه آنها را مشاهده کنید اینجا. Sinon.js، روی از سوی دیگر، روشهای کمتری برای کار با مسخرهها دارد و یک API به طور کلی سادهتر را در معرض نمایش میگذارد.
- Sinon.js کشتی را به عنوان بخشی از کتابخانه Sinon.js مسخره می کند که می تواند وصل شود و در ترکیب با سایر چارچوب های آزمایشی مانند Mocha و کتابخانه های ادعایی مانند Chai استفاده شود. شوخی می کند، روی از سوی دیگر، ارسال به عنوان بخشی از چارچوب Jest، که همچنین با API ادعاهای خود ارسال می شود.
مسخرههای Sinon.js اغلب زمانی سودمندتر هستند که در حال آزمایش یک برنامه کوچک هستید که ممکن است به کل قدرت چارچوبی مانند Jest نیاز نداشته باشد. همچنین زمانی مفید است که در حال حاضر یک تنظیمات آزمایشی داشته باشید و نیاز به اضافه کردن تمسخر به چند مؤلفه در برنامه خود داشته باشید.
با این حال، هنگام کار با برنامه های کاربردی بزرگ که وابستگی های زیادی دارند، از اهرم استفاده کنید روی قدرت API ساختگی Jest در کنار چارچوب آن می تواند برای اطمینان از یک تجربه آزمایشی ثابت بسیار مفید باشد.
نتیجه
در این مقاله به این موضوع پرداخته ایم که چگونه می توانیم از Jest برای تمسخر تماس HTTP استفاده کنیم axios
. ابتدا برنامه را برای استفاده تنظیم کردیم axios
به عنوان کتابخانه درخواست HTTP ما و سپس راه اندازی Jest برای کمک به ما در تست واحد. در نهایت، ما برخی از تفاوتهای Sinon.js و جست را بررسی کردهایم و اینکه چه زمانی میتوانیم از هر کدام به بهترین شکل استفاده کنیم.
برای مطالعه بیشتر در مورد جست و روش استفاده از آنها برای موارد استفاده پیشرفته تر، مستندات آنها را بررسی کنید. اینجا.
مثل همیشه، کد این آموزش را می توانید پیدا کنید روی GitHub.
(برچسبها برای ترجمه)# جاوا اسکریپت
منتشر شده در 1403-01-21 02:02:04