• בלוג
  • [ריאקט] זהירות! מידע גלובאלי בין בדיקות

[ריאקט] זהירות! מידע גלובאלי בין בדיקות

נתבונן בקומפוננטה הבאה מתוך דף הפתיחה של swr:

import useSWR from 'swr'

function Profile () {
  const { data, error, isLoading } = useSWR('/api/user/123', fetcher)

  if (error) return <div>failed to load</div>
  if (isLoading) return <div>loading...</div>

  // render data
  return <div>hello {data.name}!</div>
}

ונכתוב תוכנית בדיקה שמשנה את fetch כדי להחזיר אוביקט שלנו, בשביל שאפשר יהיה לבדוק את הקומפוננטה גם בלי לצאת לרשת:


import { render, screen } from '@testing-library/react';
import Profile from './Profile;

test('test one', async () => {
  jest.spyOn(global, 'fetch').mockImplementation(url => Promise.resolve({
    json: () => Promise.resolve({ name: 'bug'})
  }));

  render(<Profile />);
  expect(await screen.findByText(/hello bug/));
});

קודם כל תשמחו לשמוע שהתוכנית עובדת. עכשיו קראו את הקוד שוב. רואים את הבעיה?

תוכן עניינים

  1. מה נשבר

1. מה נשבר

בשביל לראות את הקוד נשבר צריך רק להוסיף עוד בדיקה:

test('test two', async () => {
  jest.spyOn(global, 'fetch').mockImplementation(url => Promise.resolve({
    json: () => Promise.resolve({ name: 'oh no'})
  }));

  render(<Profile />);
  expect(await screen.findByText(/hello oh no/));
});

הפעם הבדיקה השניה כבר נכשלת. קריאה בלוג תספר לכם שהכישלון קרה בגלל שעל המסך מופיעה ההודעה hello bug, שהתקבלה בתשובה הקודמת של ה API. ומה שיותר גרוע, כשתנסו לדלג על הבדיקה הראשונה הבדיקה השניה תתחיל לעבוד.

מה?

כשיש לנו בדיקות שכל אחת לבד מצליחה אבל יחד נכשלות זה רמז מאוד עבה למידע גלובאלי שמשותף לשתי הבדיקות. בדוגמה כאן המידע הגלובאלי הוא ה Cache של swr. ברגע ש swr מושך פעם אחת את התשובה מהשרת עבור URL מסוים, הוא זוכר את התשובה ומשתמש בה גם לבדיקות הבאות. באופן רגיל ה Cache נשמר בתור מפה גלובאלית שמשותפת לכל הבדיקות בתוכנית.

הפיתרון הקל במקרה הזה הוא להשתמש ב Cache נפרד לכל בדיקה באמצעות הצגת הקומפוננטה בתוך SWRConfig שונה עם Cache משלו כמו שמוצע בדיון הזה. במקרה הכללי יותר חשוב לשים לב כשאנחנו כותבים בדיקות למידע הגלובאלי שמשפיע על הבדיקות שלנו ולנקות אותו כך שכל בדיקה תוכל באמת לרוץ בצורה עצמאית.