【问题标题】:Testing Gatsby component with MDX and graphql data使用 MDX 和 graphql 数据测试 Gatsby 组件
【发布时间】:2021-03-18 22:05:33
【问题描述】:

我正在尝试在 Jest 中为组件“Step.js”编写单元测试,该组件用作使用 GraphQL 数据动态创建页面的模板。我在测试中提供了假数据,希望它可以通过 GraphQL 查询来解决。但我收到一条错误消息,提示“语法错误:无法在模块外使用 import 语句”。

从那以后,我尝试了:

  1. 在文件中添加一个“静态查询”模拟,希望在测试环境中生成假数据。但我收到了同样的错误消息。
  2. 在“moduleNameMapper”配置选项中添加“mdx”。我仍然收到同样的错误消息。
  3. 我的下一次尝试可能是安装“Jest-transformer-mdx”,看看是否可以将其添加到“jest.config.js”中。

我只是想知道对于这个问题是否有任何建议?或者有没有人遇到过这种情况?如果您有什么建议,请分享!提前谢谢?????????

这是代码,

Step.js

import React from "react"
import { graphql } from "gatsby"
import { MDXRenderer } from "gatsby-plugin-mdx"
import Layout from "./layout"
import style from "./step.module.css"

export default function Step({ data }) {
  const mdx = data.mdx
  return (
    <div>
      <h1 className={style.title}>{mdx.frontmatter.title}</h1>
      <Layout>
        <MDXRenderer>{mdx.body}</MDXRenderer>
      </Layout>
    </div>
 )
}

export const query = graphql`
  query($slug: String!) {
    mdx(fields: { slug: { eq: $slug } }) {
      body
      frontmatter {
        title
      }
    }
  }
`

Step.test.js

import React from "react"
import renderer from "react-test-renderer"
import { StaticQuery } from "gatsby"
import Step from "../src/components/step"

beforeEach(() => {
  StaticQuery.mockImplementationOnce(({ render }) => {
    render({
        mdx: {
          body: "function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }\n\nfunction _objectWithoutProperties(source, excluded) { if (source == null) return {}; var target = _objectWithoutPropertiesLoose(source, excluded); var key, i; if (Object.getOwnPropertySymbols) { var sourceSymbolKeys = Object.getOwnPropertySymbols(source); for (i = 0; i < sourceSymbolKeys.length; i++) { key = sourceSymbolKeys[i]; if (excluded.indexOf(key) >= 0) continue; if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue; target[key] = source[key]; } } return target; }\n\nfunction _objectWithoutPropertiesLoose(source, excluded) { if (source == null) return {}; var target = {}; var sourceKeys = Object.keys(source); var key, i; for (i = 0; i < sourceKeys.length; i++) { key = sourceKeys[i]; if (excluded.indexOf(key) >= 0) continue; target[key] = source[key]; } return target; }\n\n/* @jsxRuntime classic */\n\n/* @jsx mdx */\nvar _frontmatter = {\n  \"title\": \"Homebrew\"\n};\nvar layoutProps = {\n  _frontmatter: _frontmatter\n};\nvar MDXLayout = \"wrapper\";\nreturn function MDXContent(_ref) {\n  var components = _ref.components,\n      props = _objectWithoutProperties(_ref, [\"components\"]);\n\n  return mdx(MDXLayout, _extends({}, layoutProps, props, {\n    components: components,\n    mdxType: \"MDXLayout\"\n  }), mdx(\"p\", null, \"It's important to keep your programs up to date, to check to see if anything is outdated, you can use this command:\"), mdx(CommandBox, {\n    mdxType: \"CommandBox\"\n  }, \"brew outdated\"), mdx(\"p\", null, \"And to update:\"), mdx(CommandBox, {\n    mdxType: \"CommandBox\"\n  }, \"brew update\"), mdx(\"p\", null, \"If anything has gone wrong with your installation or update, you can uninstall Homebrew and start again:\"), mdx(CommandBox, {\n    mdxType: \"CommandBox\"\n  }, \"/bin/bash -c \\\"$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/uninstall.sh)\\\"\"), mdx(StepButton, {\n    to: \"/step-4\",\n    mdxType: \"StepButton\"\n  }));\n}\n;\nMDXContent.isMDXComponent = true;",
          frontmatter: {
            title: "Homebrew"
          },
        },
    })
  })
})


describe("Step component", () => {
  it("render step content on the page", () => {
    const data = {
        mdx: {
          body: "function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }\n\nfunction _objectWithoutProperties(source, excluded) { if (source == null) return {}; var target = _objectWithoutPropertiesLoose(source, excluded); var key, i; if (Object.getOwnPropertySymbols) { var sourceSymbolKeys = Object.getOwnPropertySymbols(source); for (i = 0; i < sourceSymbolKeys.length; i++) { key = sourceSymbolKeys[i]; if (excluded.indexOf(key) >= 0) continue; if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue; target[key] = source[key]; } } return target; }\n\nfunction _objectWithoutPropertiesLoose(source, excluded) { if (source == null) return {}; var target = {}; var sourceKeys = Object.keys(source); var key, i; for (i = 0; i < sourceKeys.length; i++) { key = sourceKeys[i]; if (excluded.indexOf(key) >= 0) continue; target[key] = source[key]; } return target; }\n\n/* @jsxRuntime classic */\n\n/* @jsx mdx */\nvar _frontmatter = {\n  \"title\": \"Homebrew\"\n};\nvar layoutProps = {\n  _frontmatter: _frontmatter\n};\nvar MDXLayout = \"wrapper\";\nreturn function MDXContent(_ref) {\n  var components = _ref.components,\n      props = _objectWithoutProperties(_ref, [\"components\"]);\n\n  return mdx(MDXLayout, _extends({}, layoutProps, props, {\n    components: components,\n    mdxType: \"MDXLayout\"\n  }), mdx(\"p\", null, \"It's important to keep your programs up to date, to check to see if anything is outdated, you can use this command:\"), mdx(CommandBox, {\n    mdxType: \"CommandBox\"\n  }, \"brew outdated\"), mdx(\"p\", null, \"And to update:\"), mdx(CommandBox, {\n    mdxType: \"CommandBox\"\n  }, \"brew update\"), mdx(\"p\", null, \"If anything has gone wrong with your installation or update, you can uninstall Homebrew and start again:\"), mdx(CommandBox, {\n    mdxType: \"CommandBox\"\n  }, \"/bin/bash -c \\\"$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/uninstall.sh)\\\"\"), mdx(StepButton, {\n    to: \"/step-4\",\n    mdxType: \"StepButton\"\n  }));\n}\n;\nMDXContent.isMDXComponent = true;",
          frontmatter: {
            title: "Homebrew"
          },
        },
    }

    const tree = renderer.create(<Step data={data}/>).toJSON()
    expect(tree).toMatchSnapshot()
  });
});

jest.config.js

module.exports = {
  transform: {
    "^.+\\.jsx?$": `<rootDir>/jest-preprocess.js`,
  },
  moduleNameMapper: {
    ".+\\.(css|styl|less|sass|scss)$": `identity-obj-proxy`,
    ".+\\.(jpg|jpeg|png|gif|eot|otf|webp|svg|ttf|woff|woff2|mp4|webm|wav|mp3|m4a|aac|oga)$": `<rootDir>/__mocks__/file-mock.js`,
  },
  testPathIgnorePatterns: [`node_modules`, `\\.cache`, `<rootDir>.*/public`],
  transformIgnorePatterns: [`node_modules/(?!(gatsby)/)`],
  globals: {
    __PATH_PREFIX__: ``,
  },
  testURL: `http://localhost`,
  setupFiles: [`<rootDir>/loadershim.js`],
}

【问题讨论】:

    标签: unit-testing jestjs graphql config gatsby


    【解决方案1】:

    所以在一些帮助下,我终于通过了测试。似乎 Jest 无法找到“gatsby-plugin-mdx”模块及其“MDXRenderer”模块。所以我嘲笑他们并返回传入的'孩子'。

    import React from "react"
    import renderer from "react-test-renderer"
    import { StaticQuery } from "gatsby"
    import Step from "../src/components/step"
    
    
    jest.mock("gatsby-plugin-mdx", () => {
      return { MDXRenderer: ({children}) => {
        return <div>{children}</div>;
      } }
    });
    
    beforeEach(() => {
      StaticQuery.mockImplementationOnce(({ render }) => {
        render({
            mdx: {
              body: "function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }\n\nfunction _objectWithoutProperties(source, excluded) { if (source == null) return {}; var target = _objectWithoutPropertiesLoose(source, excluded); var key, i; if (Object.getOwnPropertySymbols) { var sourceSymbolKeys = Object.getOwnPropertySymbols(source); for (i = 0; i < sourceSymbolKeys.length; i++) { key = sourceSymbolKeys[i]; if (excluded.indexOf(key) >= 0) continue; if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue; target[key] = source[key]; } } return target; }\n\nfunction _objectWithoutPropertiesLoose(source, excluded) { if (source == null) return {}; var target = {}; var sourceKeys = Object.keys(source); var key, i; for (i = 0; i < sourceKeys.length; i++) { key = sourceKeys[i]; if (excluded.indexOf(key) >= 0) continue; target[key] = source[key]; } return target; }\n\n/* @jsxRuntime classic */\n\n/* @jsx mdx */\nvar _frontmatter = {\n  \"title\": \"Homebrew\"\n};\nvar layoutProps = {\n  _frontmatter: _frontmatter\n};\nvar MDXLayout = \"wrapper\";\nreturn function MDXContent(_ref) {\n  var components = _ref.components,\n      props = _objectWithoutProperties(_ref, [\"components\"]);\n\n  return mdx(MDXLayout, _extends({}, layoutProps, props, {\n    components: components,\n    mdxType: \"MDXLayout\"\n  }), mdx(\"p\", null, \"It's important to keep your programs up to date, to check to see if anything is outdated, you can use this command:\"), mdx(CommandBox, {\n    mdxType: \"CommandBox\"\n  }, \"brew outdated\"), mdx(\"p\", null, \"And to update:\"), mdx(CommandBox, {\n    mdxType: \"CommandBox\"\n  }, \"brew update\"), mdx(\"p\", null, \"If anything has gone wrong with your installation or update, you can uninstall Homebrew and start again:\"), mdx(CommandBox, {\n    mdxType: \"CommandBox\"\n  }, \"/bin/bash -c \\\"$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/uninstall.sh)\\\"\"), mdx(StepButton, {\n    to: \"/step-4\",\n    mdxType: \"StepButton\"\n  }));\n}\n;\nMDXContent.isMDXComponent = true;",
              frontmatter: {
                title: "Homebrew"
              },
            },
        })
      })
    })
    
    
    describe("Step component", () => {
      it("render step content on the page", () => {
        const data = {
            mdx: {
              body: "function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }\n\nfunction _objectWithoutProperties(source, excluded) { if (source == null) return {}; var target = _objectWithoutPropertiesLoose(source, excluded); var key, i; if (Object.getOwnPropertySymbols) { var sourceSymbolKeys = Object.getOwnPropertySymbols(source); for (i = 0; i < sourceSymbolKeys.length; i++) { key = sourceSymbolKeys[i]; if (excluded.indexOf(key) >= 0) continue; if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue; target[key] = source[key]; } } return target; }\n\nfunction _objectWithoutPropertiesLoose(source, excluded) { if (source == null) return {}; var target = {}; var sourceKeys = Object.keys(source); var key, i; for (i = 0; i < sourceKeys.length; i++) { key = sourceKeys[i]; if (excluded.indexOf(key) >= 0) continue; target[key] = source[key]; } return target; }\n\n/* @jsxRuntime classic */\n\n/* @jsx mdx */\nvar _frontmatter = {\n  \"title\": \"Homebrew\"\n};\nvar layoutProps = {\n  _frontmatter: _frontmatter\n};\nvar MDXLayout = \"wrapper\";\nreturn function MDXContent(_ref) {\n  var components = _ref.components,\n      props = _objectWithoutProperties(_ref, [\"components\"]);\n\n  return mdx(MDXLayout, _extends({}, layoutProps, props, {\n    components: components,\n    mdxType: \"MDXLayout\"\n  }), mdx(\"p\", null, \"It's important to keep your programs up to date, to check to see if anything is outdated, you can use this command:\"), mdx(CommandBox, {\n    mdxType: \"CommandBox\"\n  }, \"brew outdated\"), mdx(\"p\", null, \"And to update:\"), mdx(CommandBox, {\n    mdxType: \"CommandBox\"\n  }, \"brew update\"), mdx(\"p\", null, \"If anything has gone wrong with your installation or update, you can uninstall Homebrew and start again:\"), mdx(CommandBox, {\n    mdxType: \"CommandBox\"\n  }, \"/bin/bash -c \\\"$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/uninstall.sh)\\\"\"), mdx(StepButton, {\n    to: \"/step-4\",\n    mdxType: \"StepButton\"\n  }));\n}\n;\nMDXContent.isMDXComponent = true;",
              frontmatter: {
                title: "Homebrew"
              },
            },
        }
    
        const tree = renderer.create(<Step data={data}/>).toJSON()
        expect(tree).toMatchSnapshot()
      });
    });
    

    如果有人有任何反馈或发现任何其他问题,请告诉我。谢谢!

    【讨论】:

      猜你喜欢
      • 2022-01-25
      • 2020-03-24
      • 1970-01-01
      • 2021-03-25
      • 1970-01-01
      • 2019-03-02
      • 2021-11-22
      • 2021-07-22
      • 2020-04-22
      相关资源
      最近更新 更多