使用覆盖的全局接口运行 mocha 测试时 tsconfig.json 编译问题

Posted

技术标签:

【中文标题】使用覆盖的全局接口运行 mocha 测试时 tsconfig.json 编译问题【英文标题】:tsconfig.json compile problem when running mocha tests with overwritten global interfaces 【发布时间】:2019-03-23 01:05:11 【问题描述】:

我正在尝试为我的 nodejs 服务器应用程序编写测试,现在一切正常。我可以将我的代码从 typescript 编译为 javascript 而没有任何错误,但是当我尝试运行 mocha 测试时,typescript 预编译失败,因为在typings.d.ts 中找不到我自己定义的类型。

这是我在typings.d.ts中的声明

import User from "./users/user.model";
import MainDatabase from "./core/models/database.model";
import Translation from "./core/services/i18n";
import LanguageDefinition from "./core/models/language.model";
import Reminder from "./core/services/schedule/schedule.model";
import UserProfileModel from "./core/database/models/user_profile";
import UserClientModel from "./core/database/models/user_client";
import PhoneNumberModel from "./core/database/models/phone_number";
import CountryModel from "./core/database/models/country";
import CustomerTypeModel from "./core/database/models/customer/customer_type";
import CustomerModel from "./core/database/models/customer/customer";
import ReminderModel from "./core/database/models/reminder_options";
import Customer from "./customers/customer.model";
import IUserAccount from "./core/database/models/user_account";
import UserAccountModel from "./core/database/models/user_account";
import MailModel from "./core/services/mail/mail.model";
import Request from "express";
import Models from "sequelize";

declare global 
  module NodeJS 
    interface Global 
      translation: Translation;
      db: MainDatabase;

      /*Classes to be reach through the global object*/
      User: User;
      Reminder: Reminder;
      Customer: Customer;
      Mailer: MailModel;
    
  



declare module "Express"
  export interface Request 
    user?: IUserAccount;
    authenticated: boolean;
    locals: 
      files?: File[];
    ;
    locale?: LanguageDefinition;
    info?:
      userAgent?: string;
      ip?: string;
    
  


// extending the original sequelize interfaces
declare module "sequelize" 

  /**
   * Database models
   * only list SEQUELIZE Models here not classes
   * */
  interface Models 
    UserProfile: UserProfileModel;
    UserAccount: UserAccountModel;
    UserClient: UserClientModel;
    Reminder: ReminderModel;
    PhoneNumber: PhoneNumberModel,
    CustomerType: CustomerTypeModel,
    Customer: CustomerModel,
    Country: CountryModel
  

在我的app.ts 中,我通过从原始包中导入原始接口/类型来使用这些类型

//omitted for brevity
/**
 * Setup all globals that do not belong to the database
 * */
private setupServerGlobals() 
  try 
    global.Mailer = new MailModel();
   catch (e) 
    console.error('setupServerGlobals', e);
  


private setupTranslation(): Observable<any> 
  // create translation
  const translation = new Translation(
    language:  language: 'de', fullLanguage: 'de' ,
  );
return translation.init().pipe(
  tap(() => 
    global.translation = translation;
  ),
);

现在,当我运行tsc --watch &amp; nodemon ./dist/src/app.js 时,所有文件都已成功编译,服务器启动时没有任何问题。由于我的 tsconfig.json 配置,编译器可以看到我在 typings.d.ts 中的全局定义类型。

但是当我运行tsc &amp; mocha 时会抛出这个错误:

/Users/user/Documents/Project/subfolder/project-name/node_modules/ts-node/src/index.ts:261
    return new TSError(diagnosticText, diagnosticCodes)
           ^
TSError: ⨯ Unable to compile TypeScript:
src/app.ts(60,14): error TS2339: Property 'Mailer' does not exist on type 'Global'.
src/app.ts(78,11): error TS2339: Property 'info' does not exist on type 'Request'.
src/app.ts(156,16): error TS2339: Property 'translation' does not exist on type 'Global'.

我的设置如下所示: + 我在每个要测试的文件旁边都有所有测试文件 + 我有一个测试文件夹,我的 mocha.opts 文件在其中

这里是我的mocha.opts 文件的内容:

src/**/*.spec.ts
--require ts-node/register
--recursive

最后这是我的tsconfig.json 文件:


  "compilerOptions": 
    "target": "es6",
    "module": "commonjs",
    "moduleResolution": "node",
    "allowSyntheticDefaultImports": true,
    "allowJs": true,
    "importHelpers": true,
    "jsx": "react",
    "alwaysStrict": true,
    "sourceMap": true,
    "forceConsistentCasingInFileNames": true,
    "noFallthroughCasesInSwitch": true,
    "noImplicitReturns": true,
    "noUnusedLocals": false,
    "noUnusedParameters": false,
    "noImplicitAny": false,
    "noImplicitThis": false,
    "strictNullChecks": false,
    "outDir": "dist"
  ,
  "include": ["**/*.ts"]

期待

像运行服务器一样运行我的测试,而不会出现编译问题。

感谢所有帮助。

编辑

我可以通过从typings.d.ts 导入类型来解决我的问题,就像在我的app.ts 文件中一样

import * as typings from './typings';

但对我来说,这似乎不是解决这个问题的好方法,因为在每个文件中我都将使用 global 变量,我需要重新导入上面的类型。

如果您知道如何解决,请随时解决此问题。

【问题讨论】:

【参考方案1】:

就我而言,我将以下内容插入tsconfig.json


  "ts-node": 
    "transpileOnly": true
  ,
  "compilerOptions": 
    ...
  

它有效。

【讨论】:

【参考方案2】:

TypeScript 在tsconfig.json 中包含以下typeRoots and types 配置:

"typeRoots": [
    "./node_modules/@types",
    "./typings"
],
"types": [
   "mocha"
]

如果指定了 typeRoots,则只包含 typeRoots 下的包 typeRoots:在这些文件夹中查找类型。

如果指定了类型,则仅包含列出的包。例如摩卡。如果您需要 typeRoots 中的所有包(如您的情况),则不要提供类型选项。指定 "types": [] 将禁用自动包含 @types 包。

【讨论】:

是的,我知道这些配置,但它们只是排除了我的类型或@types 中的类型,但我希望@types 中的这些类型和typings.d.ts 中的类型在编译时合并。跨度> 即使"./node_modules/@types""./typings"都提供了也排除在外吗? 不,它当然可以工作,但问题是 当我运行测试时,打字稿编译器无法识别打字。正常运行我的服务器时(不通过 mocha/chai .spec 文件测试他)它工作正常。

以上是关于使用覆盖的全局接口运行 mocha 测试时 tsconfig.json 编译问题的主要内容,如果未能解决你的问题,请参考以下文章

如何运行用 TypeScript 编写的 Mocha 测试?

使用来自 WebPack.DefinePlugin 的全局注入变量进行 NodeJS Mocha 单元测试

如何在 vs 代码中使用 mocha 生成覆盖率报告?

Grunt-Mocha-Test BlanketJS 覆盖范围

您如何安装和运行 Mocha,Node.js 测试模块?安装后获取“mocha:找不到命令”

使用配置表+Mocha动态生成用例的JSAPI自动化测试