首页 > 解决方案 > 代码拆分 ReactJS 组件以分离 API 调用函数在导入提取的函数时测试失败

问题描述

这是目录结构

resources/js/containers/Grid
├── Grid.js
├── getAllBlogsPreview.js
└── package.json

getAllBlogsPreview被导入到 Grid

import getAllBlogsPreview from "./getAllBlogsPreview";

是一个调用axis并返回带有一些数据的结果的函数。

export default function getAllBlogsPreview({ blogs = [], showGrid = false }) {
    Axios.get("/api/blogs")
        .then(response => {
            blogs = response.data;
            showGrid = false;
        })
        .catch(error => {
            console.log(error);
        });
    let result = {
        blogs: blogs,
        showGrid: showGrid
    };
    return result;
}

将其移出,因为无法使用componentDidMount方法和某些refreshTable方法直接执行这些 api 调用来测试组件。所以现在在我拥有的组件中

componentDidMount() {
    this.updateBlogsTable();
}

updateBlogsTable() {
    let result = getAllBlogsPreview();
    this.setState({ blogs: result.blogs });
    this.setState({ showGrid: result.showGrid });
}

这个想法是我应该能够模拟 Grid 的实现,getAllBlogsPreview从而测试 Grid 而不会被解决承诺所困。

测试失败,因为它尝试getAllBlogsPreview从测试文件本身加载

// the component to test
import Grid from "../../containers/Grid/Grid";
import getAllBlogsPreview from "../../containers/Grid/getAllBlogsPreview";
jest.mock("getAllBlogsPreview");

    describe("Blog Grid", () => {
        const result = {
            blogs: {
                data: [
                    {
                        title: "title one",
                        published: false,
                        publish_date: null,
                        slug: "title-one"
                    }
                ],
                links: {
                    self: "link-value",
                    first: "http://adminpanel.test/api/blogs?page=1",
                    last: null,
                    prev: null,
                    next: null
                },
                meta: {
                    current_page: 1,
                    from: 1,
                    path: "http://adminpanel.test/api/blogs",
                    per_page: 20,
                    to: 2
                }
            },
            showGrid: true
        };
        const getAllBlogsPreviewSpy = getAllBlogsPreview;

        beforeEach(() => {
            getAllBlogsPreviewSpy.mockImplementation(() => result);
        });
        afterEach(() => {
            getAllBlogsPreviewSpy.mockRestore();
        });

错误

FAIL   UnitTests  resources/js/tests/Blogs/Grid.test.js
  ● Test suite failed to run

    Cannot find module 'getAllBlogsPreview' from 'Grid.test.js'

       9 | import Grid from "../../containers/Grid/Grid";
      10 | import getAllBlogsPreview from "../../containers/Grid/getAllBlogsPreview";
    > 11 | jest.mock("getAllBlogsPreview");
         |      ^
      12 | 
      13 | describe("Blog Grid", () => {
      14 |     const result = {

      at Resolver.resolveModule (../../node_modules/jest-resolve/build/index.js:276:11)
      at Object.<anonymous> (tests/Blogs/Grid.test.js:11:6)

标签: reactjsjestjs

解决方案


您应该模拟模块,而不仅仅是名称(它不只通过该名称知道模块,它需要一个路径):

jest.mock("../../containers/Grid/getAllBlogsPreview");

这是更详细的解释:https ://jestjs.io/docs/en/es6-class-mocks


推荐阅读