使用 webpack

    我们通过以下常见的webpack 配置文件,将其转化为符合Jest使用的配置。

    webpack.config.js

    If you have JavaScript files that are transformed by Babel, you can by installing the plugin. Non-Babel JavaScript transformations can be handled with Jest’s transform config option. Non-Babel JavaScript transformations can be handled with Jest’s config option.

    接下来,让我们配置Jest,使其优雅地处理资源文件,如样式表和图像。 通常,这些文件在测试中无足轻重,因为我们可以安全地mock他们。 然而, 如果你使用CSS模块,那么最好是给你的类名查找模拟一个代理。

    package.json

    1. {
    2. "jest": {
    3. "moduleNameMapper": {
    4. "\\.(jpg|jpeg|png|gif|eot|otf|webp|svg|ttf|woff|woff2|mp4|webm|wav|mp3|m4a|aac|oga)$": "<rootDir>/__mocks__/fileMock.js",
    5. "\\.(css|less)$": "<rootDir>/__mocks__/styleMock.js"
    6. }
    7. }
    8. }

    所有mock文件本身:

    __mocks__/styleMock.js

    1. module.exports = {};

    __mocks__/fileMock.js

    1. module.exports = 'test-file-stub';

    你可以使用 ES6 Proxy来模拟一个 :

    • npm
    • Yarn
    1. npm install --save-dev identity-obj-proxy

    package.json (for CSS Modules)

    1. {
    2. "jest": {
    3. "moduleNameMapper": {
    4. "\\.(jpg|jpeg|png|gif|eot|otf|webp|svg|ttf|woff|woff2|mp4|webm|wav|mp3|m4a|aac|oga)$": "<rootDir>/__mocks__/fileMock.js",
    5. "\\.(css|less)$": "identity-obj-proxy"
    6. }
    7. }
    8. }

    如果 moduleNameMapper 不能满足你的需要,你就需要使用Jest的transform 来自定义对那些文件后缀应该如何转译。 例如,一个输出不带文件后缀的文件名 (such that require('logo. jpg'); returns 'logo') 应该这样写:

    fileTransformer.js

    1. const path = require('path');
    2. module.exports = {
    3. process(sourceText, sourcePath, options) {
    4. code: `module.exports = ${JSON.stringify(path.basename(sourcePath))};`,
    5. };
    6. },
    7. };

    package.json (for custom transformers and CSS Modules)

    1. {
    2. "jest": {
    3. "moduleNameMapper": {
    4. },
    5. "transform": {
    6. "\\.(jpg|jpeg|png|gif|eot|otf|webp|svg|ttf|woff|woff2|mp4|webm|wav|mp3|m4a|aac|oga)$": "<rootDir>/fileTransformer.js"
    7. }
    8. }
    9. }

    我们已经告知Jest忽略相关匹配的样式表或者图像文件,相反,导入我们的模拟文件。 你可以通过调整正规表达式来匹配webpack可以处理的文件类型。

    tip

    记住,如果你想将它和其他代码预处理器一起使用,那必须要显式地引入默认的 babel-jest 转译器,

    1. "transform": {
    2. "\\.[jt]sx?$": "babel-jest",
    3. "\\.css$": "some-css-transformer",
    4. }

    现在Jest知道如何处理我们的文件了, 接下来我们需要告诉它如何找到它们。 webpack的modulesDirectories, 和 extensions 选项都是和Jest的moduleDirectoriesmoduleFileExtensions选项类似的.

    package.json

    package.json

    1. {
    2. "jest": {
    3. "modulePaths": ["/shared/vendor/modules"],
    4. "moduleFileExtensions": ["js", "jsx"],
    5. "moduleDirectories": ["node_modules", "bower_components", "shared"],
    6. "moduleNameMapper": {
    7. "\\.(css|less)$": "<rootDir>/__mocks__/styleMock.js",
    8. "\\.(gif|ttf|eot|svg)$": "<rootDir>/__mocks__/fileMock.js"
    9. }
    10. }
    11. }

    最后,我们关注一下Webpack的alias。 在这里,我们可以再次使用 moduleNameMapper

    package.json

    1. {
    2. "moduleFileExtensions": ["js", "jsx"],
    3. "moduleDirectories": ["node_modules", "bower_components", "shared"],
    4. "moduleNameMapper": {
    5. "\\.(css|less)$": "<rootDir>/__mocks__/styleMock.js",
    6. "\\.(gif|ttf|eot|svg)$": "<rootDir>/__mocks__/fileMock.js",
    7. "^react(.*)$": "<rootDir>/vendor/react-master$1",
    8. "^config$": "<rootDir>/configs/app-config.js"
    9. }
    10. }
    11. }

    配置完成。 webpack 是一个复杂和灵活的工具,所以你可能需要做一些调整,以符合你的特定应用的需要。 幸运的是对于大多数项目来说,使用Jest来处理webpack配置,应该会更灵活。

    使用 webpack 2

    webpack 2 提供原生支持ES模块。 然而,Jest在Node中使用时需要将ES模块转化为CommonJS模块。 因此,如果你使用webpack 2,你也可能希望能配置Babel在test环境能将ES模块转化为CommonJS模块。

    .babelrc

    1. {
    2. "presets": [["env", {"modules": false}]],
    3. "env": {
    4. "test": {
    5. "plugins": ["transform-es2015-modules-commonjs"]
    6. }
    7. }
    8. }

    如果你使用动态加载 (import('some-file.js').then(module => ...)),你还需要引入Babel的动态加载插件( dynamic-import-node )。

    1. {
    2. "presets": [["env", {"modules": false}]],
    3. "plugins": ["syntax-dynamic-import"],
    4. "env": {
    5. "test": {
    6. "plugins": ["dynamic-import-node"]
    7. }
    8. }

    有关于在Webpack+React+Redux或Node的使用说明。