【问题标题】:Importing images breaks jest test导入图像打破了开玩笑的测试
【发布时间】:2018-04-04 13:11:02
【问题描述】:

在 React 组件中导入资产 (例如,从“../../../assets/img/logo.png”导入徽标) 给出这样的错误

({"Object.":function(module,exports,require,__dirname,__filename,global,jest){�PNG
SyntaxError:无效或意外的令牌 在 ScriptTransformer._transformAndBuildScript (node_modules/jest-runtime/build/script_transformer.js:305:17)

我开玩笑的配置是

"jest": {
"testRegex": ".*\\.spec\\.js$",
"moduleFileExtensions": [
  "js",
  "jsx",
  "json"
],
"moduleDirectories": [
  "node_modules",
  "src",
  "assets"
],
"moduleNameMapper": {
  "\\.(jpg|jpeg|png|gif|eot|otf|webp|svg|ttf|woff|woff2|mp4|webm|wav|mp3|m4a|aac|oga)$/": "<rootDir>/__mocks__/fileMock.js",
  "\\.(css|less|scss)$": "<rootDir>/__mocks__/styleMock.js"
},
"verbose": true,
"bail": true
}

我错过了什么?

【问题讨论】:

标签: reactjs testing webpack jestjs


【解决方案1】:

对于那些在Nuxt 2 中使用Vue test util 并面临问题或这个问题({"Object.&lt;anonymous&gt;":function(module,exports,require,__dirname,__filename,jest){ SyntaxError: Invalid or unexpected token 的人

在test/unit目录下创建一个名为fileTransformer.js的文件,然后添加以下代码:

const path = require('path')

module.exports = {
  process(src, filename, config, options) {
    return 'module.exports = ' + JSON.stringify(path.basename(filename)) + ';'
  },
}

然后将这些代码添加到jest.config.js 文件中:

  transform: {
    '\\.(jpg|jpeg|png|gif|eot|otf|webp|svg|ttf|woff|woff2|mp4|webm|wav|mp3|m4a|aac|oga)$':
    '<rootDir>/test/unit/fileTransformer.js',
    // ... other configs
  },

【讨论】:

    【解决方案2】:

    当您导入图像文件时,Jest 会尝试将图像的二进制代码解释为 .js,因此会出错。

    唯一的出路是在看到图像导入时模拟默认响应!

    我们如何做到这一点?

    • 首先您告诉 Jest 在每次遇到图像导入时运行模拟文件。你可以通过将下面的键添加到你的 package.json 文件来做到这一点
    "jest": {
     "moduleNameMapper": {
          "\\.(jpg|ico|jpeg|png|gif|eot|otf|webp|svg|ttf|woff|woff2|mp4|webm|wav|mp3|m4a|aac|oga)$": "<rootDir>/__mocks__/fileMock.js",
          "\\.(css|less)$": "<rootDir>/__mocks__/fileMock.js"
        }
    }
    

    注意:如果您已经拥有"Jest" 键,只需在其中添加"moduleNameMapper" 子项

    • 最后,在您的根目录下创建一个mocks 文件夹并在其中创建fileMock.js 文件。用下面的 sn-p 填充文件
    module.exports = ''; 
    

    注意:如果你使用的是 es6,你可以使用 export default ''; 来避免 Eslint 标志

    完成上述步骤后,您可以重新开始测试,一切顺利。

    注意。请记住在moduleNameMapper 中添加图像文件的不同扩展名,以便可以模拟它们。

    我希望我能提供帮助。 #干杯!

    【讨论】:

    • 我遇到了同样的问题,即使“moduleNameMapper”设置为你指出的那样。从问题中可以看出,问的人也是这种情况
    • 我理解您的观点,但总的来说,他可能做错了事(也许,将fileMocks.js 文件放在错误的位置或根本没有它)。我复制指南的确切原因。底线是确保文件正确命名并相应地链接到 moduleNameMapper
    • 它不适用于基于 vue.js /typescript 的测试
    • 我的文件夹名称是 mocks
    【解决方案3】:

    我遇到了同样的问题,我解决了如下:

    1. npm install -D jest-transform-stub
    2. 然后,在 package.json 中,我添加了以下转换:
    
        "jest": {
            ...
            "transform": {
                ...
                ".+\\.(css|scss|png|jpg|svg)$": "jest-transform-stub"
    

    【讨论】:

      【解决方案4】:

      我也有同样的问题!我不确定它是否与原始问题中的情况相同,但对我来说,jest 仍然以某种方式尝试将图像加载为 JS 并尝试解析它们,同时我将匹配图像扩展名的文件映射到 @987654321 中的模拟@。我的文件还包含一些将@ 字符映射到根 src 目录的代码,因为我有 webpack,并且在项目(和 TS)中将其配置为 webpack 别名。 jest.config.js 中的完整 moduleNameMapper 条目对我来说是这样的:

          moduleNameMapper: {
              '^@$': '<rootDir>/src',
              '^@/(.*)':
                  '<rootDir>/src/$1',
              '\\.(jpg|jpeg|png|gif|eot|otf|webp|svg|ttf|woff|woff2|mp4|webm|wav|mp3|m4a|aac|oga)$':
                  '<rootDir>/__mocks__/fileMock.js',
              // '\\.(css|less)$': '<rootDir>/__mocks__/styleMock.js',
              '.*\\.(css|less)$': 'identity-obj-proxy',
          }
      

      事实证明,当我在组件中导入图像时,路径类似于:'@/assets/someImage.jpg'。但是,这似乎首先匹配第一个正则表达式,即覆盖@ 别名:^@/(.*) 的那个。因此,它被映射到 &lt;rootDir&gt;/src/$1 而不是 &lt;rootDir&gt;/__mocks__/fileMock.js。

      我通过使别名仅匹配非图像来修复它:

          moduleNameMapper: {
              '^@$': '<rootDir>/src',
              '^@/(.*)\\.(?!jpg|jpeg|png|gif|eot|otf|webp|svg|ttf|woff|woff2|mp4|webm|wav|mp3|m4a|aac|oga)$':
                  '<rootDir>/src/$1',
              '.*\\.(jpg|jpeg|png|gif|eot|otf|webp|svg|ttf|woff|woff2|mp4|webm|wav|mp3|m4a|aac|oga)$':
                  '<rootDir>/__mocks__/fileMock.js',
              // '\\.(css|less)$': '<rootDir>/__mocks__/styleMock.js',
              '.*\\.(css|less)$': 'identity-obj-proxy',
          }
      

      【讨论】:

        【解决方案5】:

        对于任何研究此问题的人。您必须安装 npm install --save-dev identity-obj-proxy 才能获得必要的依赖项。

        "jest": {
            "moduleNameMapper": {
              ".+\\.(css|styl|less|sass|scss|png|jpg|ttf|woff|woff2)$": "identity-obj-proxy"
            }
          }
        

        【讨论】:

          【解决方案6】:

          如果 IOS 映像名称为 @

          moduleNameMapper: {
              "^image![a-zA-Z0-9$_-]+$": "GlobalImageStub",
              "^[@./a-zA-Z0-9$_-]+\\.(png|gif)$": "RelativeImageStub"
            }
          

          【讨论】:

            【解决方案7】:

            如果你想在 webpack 中使用 jest,你需要明确地配置它。在此处查看本指南:http://facebook.github.io/jest/docs/en/webpack.html

            【讨论】:

            • 我要补充一点,您确实需要创建 fileMock.js 和 styleMock.js 文件。我有一种情况(这是我特有的),我创建了 styleMock 但没有创建 fileMock。当我去添加我的第一张图片(png)时,当然玩笑失败了,完全是 OP 的错误。因为没有文件模拟。似乎有一个 NPM 包可以帮助解决这个问题,但它在 github 上只有 8 颗星(现在)。
            • OP没有提到webpack,这个问题与使用的包管理器类型无关。
            猜你喜欢
            • 2019-01-28
            • 2018-08-23
            • 1970-01-01
            • 2022-08-07
            • 2015-10-27
            • 2020-01-07
            • 2017-08-20
            • 1970-01-01
            相关资源
            最近更新 更多