چگونه یک تابع async را برای ایجاد یک استثنا در Jest آزمایش کنیم

به عنوان هر توسعه دهنده خوب، همیشه باید کد خود را آزمایش کنید.
و مانند هر توسعهدهندهای خوب، همیشه باید سعی کنید هنگام نوشتن توابع، استثناء را بگیرید و خطاها را کنترل کنید.
برای مثال اگر تابعی مانند این دارید:
export const logName = name => {
// do something with the name
};
تابع فوق انتظار دارد که شما همیشه یک نام تعریف شده داشته باشید، اما نمی توان آن را تضمین کرد، بنابراین کاری که باید انجام دهید این است که موردی را که نام تعریف نشده است مدیریت کنید و در آن حالت یک استثنا ایجاد کنید، و تابع شما باید به این شکل باشد. :
export const funThatThrows = name => {
if (!name) {
throw new Error('You need the name');
}
// do something with name
};
و اگر میخواهید موردی را آزمایش کنید که در آن تابع در صورت عدم عبور نام، یک استثنا برای شما ایجاد میکند، معمولاً کاری که انجام میدهید نوشتن تستی مانند این است:
describe('funThatThrows', () => {
it('should throw an error if name is missing', () => {
expect(() => {
funThatThrows();
}).toThrow();
});
});
اساساً شما تابع خود را در یک تابع ناشناس اجرا می کنید که به آن منتقل می شود expect
، و سپس بررسی می کنید که آیا این یک استثنا با the ایجاد می کند toThrow
روش.
اما چگونه آن را با توابعی که وعدهها را برمیگردانند آزمایش میکنید؟
حال، اگر تابعی دارید که به جای اجرای فوری، باید چیزی ناهمزمان را اجرا کند، و مقدار را فقط زمانی که حل شد برگرداند، چیزی شبیه به این:
export const funThatThrowsAsync = async name => {
if (!name) {
throw new Error('You need the name');
}
return Promise.resolve(`hello ${name}`);
};
و اگر سعی کنید فقط اضافه کنید async/await
به آزمایشی که قبلا انجام دادیم، چیزی شبیه به این:
describe('funThatThrowsAsync', () => {
it('should throw an error if name is missing', () => {
expect(async () => {
await funThatThrowsAsync();
}).toThrow();
});
});
مشکل بالا این است که به جای قبولی، خطای بالا فقط در پوسته شما پرتاب می شود و در تست مردود می شود:
throw new Error('You need the name');
^
Error: You need the name
کاری که باید انجام دهید تا تست به جای آن کار کند، ضمیمه کردن آن است .rejects
روش قبل از .toThrow()
، در اصل این فرمول را دارد:
expect(function).rejects.toThrow()
این به Jest میگوید که عملکرد شما در انتظار خطا است و خطا را در کنسول خاموش میکند.
بنابراین آزمون ما باید به این صورت بازنویسی شود:
describe('funThatThrowsAsync', () => {
it('should throw an error if name is missing', () => {
expect(async () => {
await funThatThrowsAsync();
}).rejects.toThrow();
});
});
و حالا آزمون شما قبول خواهد شد!
PASS src/async/async.test.js
Test throw with Async/Await
funThatThrows
✓ should throw an error if name is missing (8 ms)
funThatThrowsAsync
✓ should throw an error if name is missing (3 ms)
برای اطلاعات بیشتر می توانید به اسناد رسمی نگاهی بیندازید.