วิธีการเยาะเย้ยการใช้ตะขอประวัติศาสตร์ในการล้อเล่น?


17

ฉันใช้ UseHistory hook ใน router router v5.1.2 กับ typescript หรือไม่ เมื่อเรียกใช้การทดสอบหน่วยฉันพบปัญหา

TypeError: ไม่สามารถอ่าน 'ประวัติ' ของคุณสมบัติที่ไม่ได้กำหนด

import { mount } from 'enzyme';
import React from 'react';
import {Action} from 'history';
import * as router from 'react-router';
import { QuestionContainer } from './QuestionsContainer';

describe('My questions container', () => {
    beforeEach(() => {
        const historyHistory= {
            replace: jest.fn(),
            length: 0,
            location: { 
                pathname: '',
                search: '',
                state: '',
                hash: ''
            },
            action: 'REPLACE' as Action,
            push: jest.fn(),
            go: jest.fn(),
            goBack: jest.fn(),
            goForward: jest.fn(),
            block: jest.fn(),
            listen: jest.fn(),
            createHref: jest.fn()
        };//fake object 
        jest.spyOn(router, 'useHistory').mockImplementation(() =>historyHistory);// try to mock hook
    });

    test('should match with snapshot', () => {
        const tree = mount(<QuestionContainer />);

        expect(tree).toMatchSnapshot();
    });
});

นอกจากนี้ฉันได้ลองใช้jest.mock('react-router', () =>({ useHistory: jest.fn() }));แต่ก็ยังไม่ทำงาน

คำตอบ:


25

useHistoryผมจำเป็นต้องเหมือนกันเมื่อตื้นเขินมีการโต้ตอบองค์ประกอบการทำงานที่ใช้

แก้ไขด้วยการเยาะเย้ยต่อไปนี้ในไฟล์ทดสอบของฉัน:

jest.mock('react-router-dom', () => ({
  useHistory: () => ({
    push: jest.fn(),
  }),
}));

17

อันนี้ใช้ได้สำหรับฉัน:

jest.mock('react-router-dom', () => ({
  ...jest.requireActual('react-router-dom'),
  useHistory: () => ({
    push: jest.fn()
  })
}));

1
วิธีนี้รักษาฟังก์ชั่น react-router-dom อื่นซึ่งคุณอาจไม่ต้องการเยาะเย้ย
Pnar Sbi Wer

@ Erhan ฉันได้ทำแบบเดียวกัน แต่อีกครั้งมันเป็นข้อผิดพลาดการขว้างปา: TypeError: ไม่สามารถอ่าน 'ประวัติ' ของคุณสมบัติที่ไม่ได้กำหนด ข้อเสนอแนะใด ๆ
Mukund Kumar

6

นี่คือตัวอย่างที่ละเอียดมากขึ้นนำมาจากรหัสการทดสอบการทำงาน (เนื่องจากฉันมีปัญหาในการใช้รหัสด้านบน):

Component.js

  import { useHistory } from 'react-router-dom';
  ...

  const Component = () => {
      ...
      const history = useHistory();
      ...
      return (
          <>
              <a className="selector" onClick={() => history.push('/whatever')}>Click me</a>
              ...
          </>
      )
  });

Component.test.js

  import { Router } from 'react-router-dom';
  import { act } from '@testing-library/react-hooks';
  import { mount } from 'enzyme';
  import Component from './Component';
  it('...', () => {
    const historyMock = { push: jest.fn(), location: {}, listen: jest.fn() };
    ...
    const wrapper = mount(
      <Router history={historyMock}>
        <Component isLoading={false} />
      </Router>,
    ).find('.selector').at(1);

    const { onClick } = wrapper.props();
    act(() => {
      onClick();
    });

    expect(historyMock.push.mock.calls[0][0]).toEqual('/whatever');
  });

5

ใน github react-router repo ฉันพบว่า useHistory hook ใช้ singleton context เมื่อฉันเริ่มใช้ใน Mount MemoryRouter มันพบบริบทและเริ่มทำงาน ดังนั้นแก้ไข

import { MemoryRouter } from 'react-router-dom';
const tree =  mount(<MemoryRouter><QuestionContainer {...props} /> </MemoryRouter>);
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.