3 votes

Problème de test unitaire Jest : "module non trouvé"

Actuellement, Jest échoue les tests car il ne peut pas trouver le module appelé dans un composant :

 FAIL  tests/Unit/VHeaderBar.spec.ts
   Test suite failed to run

    Cannot find module '@@/public/assets/images/placeholder.png' from 'VHeaderBar.vue'

      at Resolver.resolveModule (node_modules/jest-runtime/node_modules/jest-resolve/build/index.js:221:17)
      at src/components/VHeaderBar.vue:687:18
      at Object.<anonymous> (src/components/VHeaderBar.vue:749:3)

Cas

En NuxtJs el @@ Les signes font référence à la Racine car dans la solution finale, nous voulons stocker les images dans le dossier public ou le dossier de stockage, qui est situé dans la racine du projet.

Lors de l'exécution des tests jest vérifie le src puis essaie de monter les images stockées à partir de la racine et ne les trouve pas.

J'ai essayé de nombreuses façons différentes de résoudre ce problème, mais je n'arrive pas à trouver la solution. Voici une liste de ce que j'ai déjà essayé :

  • Changer regex pour vérifier la présence de fichiers d'image et le diriger vers le bon dossier en utilisant la fonction moduleNameMapper dans le fichier de configuration de Jest.
  • J'ai lu quelque chose sur Stack à propos de l'utilisation d'un dossier "mock" qui exporte les fichiers d'images via javascript, mais cela n'a pas fonctionné.
  • Utilisation de la modulePaths dans le fichier de configuration de Jest.
  • Création d'un alias dans le tsconfig.js pour le actifs et de l'utiliser dans le dossier moduleNameMapper
  • J'ai essayé une approche différente dans le composant VueJS et le fichier de test pour charger les actifs, ce qui a cassé le processus de compilation (j'ai donc fait marche arrière).

Fichier Jest Config actuel

module.exports = {
    moduleFileExtensions: [
        "ts",
        "tsx",
        "vue",
        "js",
        "json"
    ],
    watchman: false,
    moduleNameMapper: {
        "/\.(gif|jpg|jpeg|tiff|png)$/i": "<rootDir>/public/assets/images/$1",
        "^@/(.*)$": "<rootDir>/src/$1",
        "^~/(.*)$": "<rootDir>/src/$1",
        "^~~/(.*)$": "<rootDir>/src/$1"
    },
    transform: {
        // process js with `babel-jest`
        "^.+\\.js$": "<rootDir>/node_modules/babel-jest",
        // process `*.vue` files with `vue-jest`
        ".*\\.(vue)$": "<rootDir>/node_modules/vue-jest",
        // process `*.ts` files with `ts-jest`
        "^.+\\.(ts|tsx)$": "<rootDir>/node_modules/ts-jest",
    },
    snapshotSerializers: [
        "<rootDir>/node_modules/jest-serializer-vue"
    ],
    collectCoverage: true,
    collectCoverageFrom: [
        "<rootDir>/src/components/**/*.vue",
        "<rootDir>/src/pages/**/*.vue",
        "<rootDir>/src/layouts/**/*.vue"
    ],
    testMatch: [
        '**/tests/Unit/**/*.spec.(js|jsx|ts|tsx)|**/__tests__/*.(js|jsx|ts|tsx)'
    ],
}

Structure actuelle des dossiers (uniquement les dossiers que nous utilisons pour le test)

project folder
- public
-- assets
--- **images**

- src
-- components
--- **mounted component** (works)

- tests
-- Unit
--- mountedComponent.spec.ts

Des suggestions ?

Est-ce que je répare le jest.config ?

Y a-t-il un problème de syntaxe ?

Est-ce que je dois réparer le tsconfig ?

0voto

J'ai eu un problème similaire et ça se résume au fait que Typescript ne peut pas importer ce fichier.

Je l'ai résolu en ajoutant la définition du type de fichier à files.d.ts :

declare module "*.pdf" {
  const file: Buffer;
  export default file;
}

declare module "*.jpeg" {
  const src: string;
  export default src;
}

declare module "*.png" {
  const src: string;
  export default src;
}

En se référant à ce fichier dans tsconfig.json :

{
  "compilerOptions": {
    /* ... */
  },
  "files": ["./src/@types/files.d.ts"],
  "include": ["src/**/*"],
  "exclude": ["node_modules"]
}

Et l'ajout de transformations de fichiers à jest.config.js :

module.exports = {
  preset: "ts-jest",
  testEnvironment: "node",
  roots: ["<rootDir>/src/"],

  moduleNameMapper: {
    "@app/(.*)": "<rootDir>/src/$1",
    "@lib/(.*)": "<rootDir>/src/lib/$1",
  },
  transform: { // Transforms here
    "\\.(gql|graphql)$": "@jagi/jest-transform-graphql",
    "\\.(html|html|txt|pem|key)$": "./jest-transform-text.js",
    "\\.(p12|pdf|otf|ttf)$": "./jest-transform-buffer.js",
    "^(?!.*\\.(js|jsx|ts|tsx|css|json)$)": "<rootDir>/config/jest/fileTransform.js"

  },
  coverageReporters: ["text", "lcov"],
};

Exemples de fichiers de transformation :

// jest-transform-buffer.js

"use strict";
const fs = require("fs");
module.exports = {
  process(src, filename) {
    const data = fs.readFileSync(filename, "hex");
    return (
      'module.exports=Buffer.from("' +
      data +
      '","hex");module.exports.default=module.exports;'
    );
  },
};

Et pour les images (ou d'autres fichiers pour lesquels vous n'avez besoin que d'un nom de fichier) à partir de la création d'une application réactive :

'use strict';

const path = require('path');
const camelcase = require('camelcase');

// This is a custom Jest transformer turning file imports into filenames.
// http://facebook.github.io/jest/docs/en/webpack.html

module.exports = {
  process(src, filename) {
    const assetFilename = JSON.stringify(path.basename(filename));

    if (filename.match(/\.svg$/)) {
      // Based on how SVGR generates a component name:
      // https://github.com/smooth-code/svgr/blob/01b194cf967347d43d4cbe6b434404731b87cf27/packages/core/src/state.js#L6
      const pascalCaseFilename = camelcase(path.parse(filename).name, {
        pascalCase: true,
      });
      const componentName = `Svg${pascalCaseFilename}`;
      return `const React = require('react');
      module.exports = {
        __esModule: true,
        default: ${assetFilename},
        ReactComponent: React.forwardRef(function ${componentName}(props, ref) {
          return {
            $$typeof: Symbol.for('react.element'),
            type: 'svg',
            ref: ref,
            key: null,
            props: Object.assign({}, props, {
              children: ${assetFilename}
            })
          };
        }),
      };`;
    }

    return `module.exports = ${assetFilename};`;
  },
};

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X