Как правильно проверить ценность файла cookie при использовании React-cookie?

Я пытаюсь протестировать следующий сценарий с помощью JestJS и мне нужен совет, как это сделать, потому что я понятия не имею, как правильно.

Когда я впервые посещаю страницу, внизу появляется баннер с кнопкой Accept Cookies. Когда пользователь нажимает кнопку, файл cookie устанавливается с помощью пакета response-cookie.

Мне нужно проверить значения этого файла cookie и проверить, являются ли они ожидаемыми.

Это код, который у меня есть до сих пор:

import { fireEvent, render, screen } from '@testing-library/react'

jest.mock('react-cookie', () => {
    __esModule: true,
    useCookies: jest.fn()
})

const mockedUseCookies == useCookies as jest.Mock<any>

describe('Cookies Banner', () => {
    it('Cookie will get proper values after click on Accept Cookies button', () => {
        render(
            <CookiesBanner {...someCookieData}></CookiesBanner>
        )

        const acceptCookiesBtn = screen.getByTestId('acceptCookiesBtn')
        fireEvent.click(acceptCookiesBtn)

        //How do I check if the cookies have the right value here???
    })
})

Но если я запущу вышеуказанный тест, он завершится ошибкой со следующей ошибкой:

TypeError: undefined is not iterable (cannot read property Symbol(Symbol.iterator))
    const [cookies, setCookie, removeCookie] = useCookies()

что мне здесь не хватает?

Я проверил следующие сообщения, и ни одно из них не соответствует моему сценарию:

Я также проверил, как пишутся тесты для библиотеки (здесь), но снова не могу заставить свой тест работать должным образом.

Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Навигация по приложениям React: Исчерпывающее руководство по React Router
Навигация по приложениям React: Исчерпывающее руководство по React Router
React Router стала незаменимой библиотекой для создания одностраничных приложений с навигацией в React. В этой статье блога мы подробно рассмотрим...
Массив зависимостей в React
Массив зависимостей в React
Все о массиве Dependency и его связи с useEffect.
0
0
276
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Вы высмеяли useCookies, чтобы иметь реализацию jest.fn(). Но баннер cookie использует его, вероятно, так:

const [cookies, setCookie, removeCookie] = useCookies(['cookie-name']);

//jest.fn returns undefined so the previous line is equivalent to:

const [cookies, setCookie, removeCookie] = undefined;

//And then it tries to get the first, second, and the third indexed item for undefined which leads to your error "undefined is not iterable" and it is true.

Правильное решение — высмеять react-cookie, но у него должен быть тот же контракт.


import { fireEvent, render, screen } from '@testing-library/react'
import { useCookies } from '@testing-library/react'

//we mock it initially for all
jest.mock('react-cookie', () => {
    __esModule: true,
    useCookies: jest.fn(() => [
       // mock for cookies
       [],
       //mock for setCookie
       jest.fn(),
       //mock for removeCookie
       jest.fn()
    ])
})

const mockedUseCookies == useCookies as jest.Mock<any>

const getCookiesSpies = () => {

  const setCookieMock = jest.fn();
  const removeCookieMock = jest.fn();

  mockedUseCookies.mockImplementation(() => ([
       // mock for cookies
       [],
       //mock for setCookie
       setCookieMock,
       //mock for removeCookie
       removeCookieMock 
    ])
  ]));

  return {setCookieMock, removeCookieMock }
}

describe('Cookies Banner', () => {

   beforeEach(() => {
       // THIS IS IMPORTANT SO THAT EACH TEST IS IN ISOLATION
      jest.clearAllMocks();
   });

  it('Cookie will get proper values after click on Accept Cookies button', () => 
  {
       // OVERIDE setCookies BEFORE RENDERING !!!!

       const {setCookieMock, removeCookieMock } = getCookiesSpies();
        render(
            <CookiesBanner {...someCookieData}></CookiesBanner>
        )

        const acceptCookiesBtn = screen.getByTestId('acceptCookiesBtn')
        fireEvent.click(acceptCookiesBtn)

        //How do I check if the cookies have the right value here???
        expect(setCookieMock).toHaveBeenCalledWith('expected-cookie-name', 'expected-cookie-value')
    })
  })

Это также можно расширить, чтобы вводить результат в параметр useCookies - cookie при вызове его для каждого теста.

Другие вопросы по теме