السخرية - لا تعض!
وهي مصممة لمساعدتك في إنشاء اختبارات أبسط وأكثر موثوقية. في هذه السلسلة من المقالات ، سأعرض لك الأنماط التي أعتمد عليها عند السخرية من مكونات React (أو "stubbing").
هذا مثال جيد على كعب مكون. أنا أستخدمها
jest.mock، والتي سنلقي نظرة عليها بمزيد من التفصيل أدناه.
jest.mock("../src/PostContent", () => ({
PostContent: jest.fn(() => (
<div data-testid="PostContent" />
))
}))
لا ينبغي أن يبدو كعب مكون React النموذجي أكثر تعقيدًا. لاحظ قيمة كعب الروتين البسيط للغاية (
div) والسمة data-testidالتي تجعل من السهل جدًا علينا العثور على مثيل مُعرض في DOM. حسب الاصطلاح ، يجب أن يتطابق معرّف الاختبار المستخدم مع اسم المكون. في هذه الحالة ، هو PostContent.
قبل أن ننظر في كيفية استخدامها ، دعنا أولاً نلقي نظرة على ماهية السخريات ولماذا قد ترغب في استخدامها.
ما هي الوهمية؟
في عالم JavaScript ، يُستخدم مصطلح mock على نطاق واسع للإشارة إلى أي تطبيق تم الاستهزاء به أو اختبار مزدوج . عمليات التنفيذ التي تم الاستهزاء بها هي ببساطة قيم تحل محل القيم الأخرى في كود الإنتاج الخاص بك أثناء إجراء الاختبارات. إنهم يحاولون على واجهة الكائن الذي يتم استبداله ، لذا يعمل باقي الكود كما لو لم يكن هناك بديل.
هناك عدة أسباب مختلفة وراء رغبتك في القيام بذلك ؛ سننظر إليهم بأمثلة.
إذا كنت مهتمًا بمعرفة المزيد حول عمليات التنفيذ التي يتم الاستهزاء بها ، فاقرأ كتاب مارتن فاولر Mocks Are Not Stubs .
الدعابة والاستهزاء
يحتوي Jest على ميزة
jest.mockتتيح لك محاكاة الوحدات النمطية بأكملها التي تستبدلها. في هذا البرنامج التعليمي ، ركزت على هذه الميزة ، على الرغم من وجود طرق أخرى لاستبدال الكائنات في JavaScript.
في كتاب Mastering React Test-Driven Development ، أستخدم استيراد الوحدات المسماة ES6 لإنشاء مضاعفات اختبار. يمنح هذا الأسلوب مزيدًا من المرونة ، لكنه يبدو أكثر دقة.
Jest jest.mockتقول أن السخريات تضمن أن تكون اختباراتك سريعة وليست هشة .
في حين أن هذا صحيح ، إلا أن هذا ليس السبب الرئيسي لاستخدام السخريات.
أستخدم السخريات لأنها تساعدني في الحفاظ على استقلالية اختباراتي عن بعضها البعض.
لفهم سبب ذلك ، دعنا نلقي نظرة على مثال.
لماذا موكي؟
يوجد أدناه قائمة بالمكون
BlogPageالذي يقوم بأمرين: يتم جلبه idمن خاصية urlثم يعرض PostContentمكونًا به id.
const getPostIdFromUrl = url =>
url.substr(url.lastIndexOf("/") + 1)
export const BlogPage = ({ url }) => {
const id = getPostIdFromUrl(url)
return (
<PostContent id={id} />
)
}
تخيل أنك تكتب اختبارات لهذا المكون ، وأن جميع اختباراتك مدرجة في
BlogPage.test.js، وهي مجموعة اختبار واحدة تغطي المكونات BlogPageو PostContent.
في هذه المرحلة ، لا تحتاج إلى السحابات حتى الآن: لم نرها
PostContentبعد ، ولكن بالنظر إلى الحجم BlogPage، لا توجد حاجة حقًا إلى مجموعتين منفصلتين للاختبار ، نظرًا BlogPageلأنها بسيطة بشكل عامPostContent .
تخيل الآن إضافة وظائف إلى
BlogPageكل من y و y PostContent. بصفتك مطورًا موهوبًا ، فأنت تضيف المزيد والمزيد من الميزات كل يوم.
يصبح من الصعب الحفاظ على الاختبارات في حالة عمل. يحتوي كل اختبار جديد على إعداد أكثر تعقيدًا ، وتبدأ مجموعة الاختبار في استهلاك المزيد من وقتك - وهو عبء يحتاج الآن إلى الدعم.
هذه مشكلة شائعة وأنا أراها دائمًا في قواعد أكواد React. مجموعات الاختبار التي يؤدي فيها حتى أبسط تغيير إلى فشل العديد من الاختبارات.
حل واحد هو تقسيم مجموعات الاختبار. سنترك
BlogPage.test.jsوننشئ PostContent.test.jsواحدًا جديدًا يجب أن يحتوي على اختبارات حصريًا PostContent. الفكرة الأساسية هي أن أي وظائف موضوعة PostContentيجب أن تكون موجودة PostContent.test.js، وأي وظائف موضوعة BlogPage(مثل تحليل عنوان URL) يجب أن تكون موجودة BlogPage.test.js.
حسنا.
ولكن ماذا لو التقديم
PostContent له آثار جانبية؟
export const PostContent = ({ id }) => {
const [ text, setText ] = useState("")
useEffect(() => {
fetchPostContent(id)
}, [id])
const fetchPostContent = async () => {
const result = await fetch(`/post?id=${id}`)
if (result.ok) {
setText(await result.text())
}
}
return <p>{text}</p>
};
BlogPage.test.jsيجب أن تكون
مجموعة الاختبار على دراية بالآثار الجانبية وأن تكون مستعدًا للتعامل معها. على سبيل المثال ، سيتعين عليه الاحتفاظ fetchبإجابة جاهزة .
التبعية التي حاولنا تجنبها عن طريق تقسيم مجموعات الاختبار الخاصة بنا لا تزال موجودة.
لقد تحسن تنظيم اختباراتنا بالتأكيد ، ولكن في النهاية ، لم يحدث شيء يجعل اختباراتنا أقل هشاشة.
لهذا نحتاج كعب (أو وهمية)
PostContent.
وفي الجزء التالي سننظر في كيفية القيام بذلك.
هل هو حقا ضروري؟
بالمناسبة ، بضع كلمات حول الانتقال من الاختبارات الشاملة إلى اختبارات الوحدة.
يعد وجود مضاعفات الاختبار مؤشرًا رئيسيًا على أنك تكتب اختبارات الوحدة.
يبدأ العديد من المختبرين المخضرمين مشاريع جديدة على الفور باختبارات الوحدة (والسخرية) لأنهم يعرفون أنه مع نمو قاعدة الكود الخاصة بهم ، سيواجهون مشكلات عدم استقرار الاختبار.
عادة ما تكون اختبارات الوحدة أصغر بكثير من الاختبارات من طرف إلى طرف. يمكن أن تكون صغيرة جدًا لدرجة أنها غالبًا لا تأخذ أكثر من ثلاثة أو أربعة أسطر من التعليمات البرمجية. هذا يجعلهم مرشحين رائعين لممارسات الترميز الاجتماعي مثل برمجة الاقتران والمجموعات.
حتى عندما نجري اختبار الوحدة ، فإن مضاعفات الاختبار ليست ضرورية دائمًا - فهي مجرد أداة أخرى في مجموعتك تحتاج إلى معرفة وقت وكيفية التقديم.
في الجزء التالي ، سوف نغطي تقنيات السخرية الأساسية .
