Невозможно найти ошибку модуля при имитации элементов в модульном тестировании Jest с помощью TypeScript в Node.js

В настоящее время я работаю над интеграцией модульного тестирования Jest в свое приложение Node.js, написанное на TypeScript. Однако я сталкиваюсь с ошибкой при попытке имитировать определенные элементы. Вот конкретная ошибка, с которой я столкнулся:

Вот упрощенная версия моего тестового файла (appcontroller.test.ts):

import 'reflect-metadata';
import AppController from '../controllers/AppController';
import { ResponseToolkit, Request } from '@hapi/hapi';
import Config from '../config/Config';

jest.mock('../controllers/AppController');
const mockToolkit = {} as ResponseToolkit;

describe('App Routes - V api', () => {
  it('should return version details', async () => {
    const mockedVersion = 'microservice-template';
    const mockedName = '0.0.1';
    const expectedResponse = {
      "data": {
        "version": "microservice-template",
        "name": "0.0.1"
      }
    };
    const mockRequest = {} as Request;
    (Config.get as jest.Mock).mockReturnValueOnce(mockedVersion).mockReturnValueOnce(mockedName);

    const mockController = jest.fn().mockResolvedValue(expectedResponse);
    const mockAppController = new AppController();
    mockAppController.getAppDetailsHandler = mockController;

    const handler = mockAppController.getAppDetailsHandler.bind(mockAppController);
    const response = await handler(mockRequest, mockToolkit);
    expect(mockController).toHaveBeenCalled();
    expect(response).toEqual(expectedResponse);
  });
});

А вот соответствующая часть моего кода TypeScript (appcontroller.ts):

import Hapi from '@hapi/hapi';
import { injectable } from 'inversify';
import Config from '@app/config/Config';
import BaseController from './BaseController';

@injectable()
export default class AppController extends BaseController {
 
  public async getAppDetailsHandler(request: Hapi.Request, h: Hapi.ResponseToolkit): Promise<Hapi.ResponseObject> {
    try {
      return this.buildResponse(h, {
        version: Config.get('serviceName'),
        name: Config.get('serviceVersion'),
      });
    } catch (error) {
      return this.handleErrors(h, error);
    }
  }
}

Конфиг.ц

import convict from 'convict';
import dotenv from 'dotenv';
export const LOGGER_TYPE_FILE = 'file';
export const LOGGER_TYPE_CONSOLE = 'console';

/** Configure Dotenv to loads environment */
dotenv.config();

const configurationSchema = convict({
  env: {
    doc: 'The application environment.',
    format: ['local', 'dev'],
    default: 'local',
    env: 'NODE_ENV',
  },
  serviceName: {
    doc: 'Name of the service. It needs to be set in the package.json file.',
    format: String,
    default: process.env.npm_package_name ?? 'service_name_not_set',
    env: 'npm_package_name',
  },
  serviceVersion: {
    doc: 'Version of the service. It needs to be set in the package.json file.',
    format: String,
    default: process.env.npm_package_version ?? 'service_version_not_set',
    env: 'npm_package_version',
  },
});

const Config = configurationSchema.validate({ allowed: 'strict' });

export default Config;

Я пробовал устранить эту неполадку с помощью разных предложений, одно из которых добавляет код ниже в jest.config.js.

 moduleNameMapper: {
    "^~(.*)$": "<rootDir>/src/$1"
  }

но я все еще застрял. Может ли кто-нибудь дать рекомендации по устранению этой ошибки?

Заранее благодарю за любую помощь!

AppController.ts не может import Config from '@app/config/Config';, поэтому ваше @app, похоже, настроено неправильно - можете ли вы вместо этого использовать относительный путь?

Jeremy 11.04.2024 19:32

@Jeremy Это решает проблему с конфигурацией, когда я меняю путь во всех файлах. Но это создает другую проблему: "env: должно быть одним из возможных значений: ["local","dev","qa","stage","prod"]: значение было "test" }); const Config = ConfigurationSchema .validate({ разрешено: 'strict' }); экспортировать конфигурацию по умолчанию;"

Athulya Ratheesh 12.04.2024 10:56

Итак, относительный путь работает, но приложение не настроено для шутки? Звучит как проблема с конфигурацией шутки, если вы заглянули в модульNameMapper и преобразовали настройки через Babel/любой транспилятор? Нужно больше места, чтобы разместить один из них, введу ответ с каким-нибудь примером.

Jeremy 13.04.2024 11:16
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
3
143
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

У Jest иногда возникают подобные проблемы с импортом машинописных текстов. Однако в вашей конфигурации Jest json вы можете указать moduleNameMapper, который может заменять части ваших путей.

{
    "moduleFileExtensions": ["js", "json", "ts"],
    "moduleNameMapper": {
        "@app": "hello"
    }
}

См. официальную документацию шутки.

Ответ принят как подходящий

Предполагая, что вы попробовали модульNameMapper согласно предложению Дэвида:

// jest.config.js

module.exports = {
  // other Jest configuration options...
  
  moduleNameMapper: {
    // Regular expression mapping module names to paths
    '^@/(.*)$': '<rootDir>/src/$1', // Example: Maps "@/components" to "<rootDir>/src/components"
    
    // Specific mappings for individual modules
    '^utils/(.*)$': '<rootDir>/src/utils/$1', // Example: Maps "utils/foo" to "<rootDir>/src/utils/foo"
    
    // Mocking CSS files
    '\\.(css|less|scss)$': 'identity-obj-proxy', // Example: Mock CSS imports using "identity-obj-proxy"
  },
};  }
}

А как насчет трансформации, правильно ли вы транспилируете?

transform: {
    '^.+\\.tsx?$': 'ts-jest', // Transform TypeScript files using ts-jest
  },
  transform: {
    // Use babel-jest to transpile tests with the next/babel preset
    // https://jestjs.io/docs/configuration#transform-objectstring-pathtotransformer--pathtotransformer-object
    '^.+\\.(js|jsx|ts|tsx)$': [
      'babel-jest',
      {
        presets: [
          [
            'next/babel',
            {
              'preset-react': {
                runtime: 'automatic',
                importSource: '@emotion/react',
              },
            },
          ],
        ],
      },
    ],
  },

Другие вопросы по теме