Jest.js 嘲笑第三方React组件没有效果

bbuxkriu  于 2023-05-11  发布在  Jest
关注(0)|答案(1)|浏览(217)

我使用jestreact testing library来为我的React应用提供基本测试。我用msw模拟了REST调用。
不幸的是,我使用的第三方库之一似乎不能在这些测试中正确地呈现输出,因为我对测试整个流程比精确的结果更感兴趣,所以我决定模拟它并用一个虚拟实现来代替。
该库是react-photo-album,我将其导入到我的组件中:

import PhotoAlbum from "react-photo-album";

我的测试看起来像:

it('loads photos', async () => {

 //mocking goes here

  const { container } = render(<MemoryRouter><Gallery /></MemoryRouter>);
  
  screen.debug();

  await waitFor(() => {
      expect(container.getElementsByClassName('mockedComponent').length).toBe(1);
   });
});

我最感兴趣的是msw响应其余调用并提供实际数据后的结果,但现在我很高兴至少看到PhotoAlbum组件在debug视图中被替换。然而,它似乎一点也不受影响。而是渲染原始组件。
现在,我已经尝试了嘲笑(已经放弃了任何花哨的逻辑):

jest.doMock('react-photo-album', () => ({
    PhotoAlbum: () => <div className="mockedComponent" />,
  }));

  jest.mock('react-photo-album', () => ({
    __esModule: true,
    PhotoAlbum: () => <div className="mockedComponent" />,
  }));

  jest.mock('react-photo-album', () => ({
    __esModule: true,
    default: () => <div className="mockedComponent" />,
  }));

  jest.mock('PhotoAlbum', () => (props) => {
    return <div className="mockedComponent" />;
  });

加上这些的多种变体,包括mockdoMock,甚至简单地说:

jest.mock('react-photo-album');

但我的零件好像没动过!.使用mock方法,我主要得到以下错误:
jest.mock()的模块工厂不允许引用任何超出范围的变量。无效的变量访问:_jsxFileName
但是doMock似乎解决了这个问题。
我做错了什么?我觉得我忽略了一些细节。为了记录,React或jest都不是我通常使用的工具。我也看到过这样的答案:How to mock a third party React component using Jest?,但它似乎不工作。

wlzqhblo

wlzqhblo1#

您遇到的错误可能特定于您的环境/项目设置,因为您在问题中提到的模拟选项之一实际上是有效的。
下面是一个工作示例:

import { render } from "@testing-library/react";
import Gallery from "../src/Gallery";

jest.mock("react-photo-album", () => ({
    __esModule: true,
    default: () => <div className="mockedComponent" />,
}));

describe("Gallery", () => {
    it("loads photos", () => {
        const { container } = render(<Gallery />);

        expect(container.getElementsByClassName("mockedComponent").length).toBe(1);
    });
});

现在,如果你想解决PhotoAlbumjest测试中没有渲染的原始问题,你可以通过模拟PhotoAlbum的容器<div>clientWidth来修复它:

import { render } from "@testing-library/react";
import Gallery from "../src/Gallery";

// mock PhotoAlbum container clientWidth
jest
    .spyOn(Element.prototype, "clientWidth", "get")
    .mockImplementation(function () {
        return (this.className || "").split(" ").includes("react-photo-album")
            ? 800
            : 0;
    });

describe("Gallery", () => {
    it("loads photos", () => {
        const { container } = render(<Gallery />);

        // test PhotoAlbum rendered 3 photos
        expect(
            container.getElementsByClassName("react-photo-album--photo").length
        ).toBe(3);
    });
});

您可以在下面的沙箱中找到最小的工作示例。
https://codesandbox.io/p/sandbox/stackoverflow-75817885-fs9y5m?file=%2Ftest%2FGalleryMock.spec.jsx

相关问题