在 Jest 测试框架中访问 Angular 服务构造函数

Posted

技术标签:

【中文标题】在 Jest 测试框架中访问 Angular 服务构造函数【英文标题】:Accessing angular service constructor in Jest testing framework 【发布时间】:2017-12-03 15:43:29 【问题描述】:

我正在努力寻找以下问题的答案(我敢打赌,答案很可能相对简单)...

我正在使用 Jest 测试框架对 Ionic 3.4 应用程序进行单元测试,但不知道如何调用 Angular 服务来测试构造函数初始化 Http 对象和 InAppBrowser Ionic Native 插件对象的位置。

我的 package.json 文件包含以下配置:

...
"jest": 
    "transform": 
        ".(ts|tsx)": "<rootDir>/node_modules/ts-jest/preprocessor.js"
    ,
    "testRegex": "(/__tests__/.*|\\.(test|spec))\\.(ts|tsx|js)$",
    "moduleFileExtensions": [
        "ts",
        "tsx",
        "js",
        "json"
    ]
,
"devDependencies": 
    "@types/jest": "^20.0.2",
    "@types/node": "^7.0.31",
    "jest": "^20.0.4",
    "ts-jest": "^20.0.6",
    "ts-node": "^3.0.6",
    "tslint": "^5.4.3",
    "tslint-eslint-rules": "^4.1.1",
    "typescript": "2.3.3"
,
...

我的 tsconfig.json 文件,位于 src/unit-tests 目录中(以便仅针对该目录及其内容,而不会干扰 Ionic 项目的根 tsconfig.json 文件),如下:


    "compilerOptions" : 
        "module"                        : "commonjs",
        "allowSyntheticDefaultImports"  : true,
        "experimentalDecorators"        : true,
        "noImplicitAny"                 : false,
        "removeComments"                : false,
        "locale"                        : "en-GB",
        "alwaysStrict"                  : true,
        "skipLibCheck"                  : true,
        "pretty"                        : true
    

请求的服务 - providers/settings/settings.ts - 如下:

import  Injectable  from '@angular/core';
import  Http  from '@angular/http';
import  InAppBrowser  from '@ionic-native/in-app-browser';
import 'rxjs/add/operator/map';


@Injectable()
export class SettingsProvider 

constructor(public http     : Http,
            private _INAPP  : InAppBrowser) 
  

// Methods follow here

然后在 settings.test.ts 文件中使用它,如下所示:

import 'reflect-metadata';
import  SettingsProvider  from '../providers/settings/settings';


let settings = null;

beforeEach(() => 
  // The following works IF the SettingsProvider class 
  // contains NO parameters in the constructor
  settings = new SettingsProvider();
);



describe('Settings service', () => 

    // Tests are defined within here
    // using methods supplied by the 
    // SettingsProvider class
);

如果我从 SettingsProvider 类构造函数中取出参数,Jest 可以完全按照预期运行测试(通过或失败)。

在 SettingsProvider 类构造函数中设置参数后,Jest 在尝试运行测试脚本时出现以下错误:

 Test suite failed to run

/ionic-unit/node_modules/@ionic-native/in-app-browser/index.js:20
import  Injectable  from '@angular/core';
^^^^^^
SyntaxError: Unexpected token import

  at ScriptTransformer._transformAndBuildScript (node_modules/jest-runtime/build/ScriptTransformer.js:289:17)
  at Object.<anonymous> (src/providers/settings/settings:12:21)
  at Object.<anonymous> (src/unit-tests/settings.test.ts:2:18)

如何配置我的测试脚本,以便 Jest 识别在 SettingsProvider 构造函数中初始化的模块?

我对单元测试还比较陌生,并且一直在尝试弄清楚如何实现这一点(但是,正如您所知,到目前为止还没有太多乐趣!)

感谢任何开发人员可能就此事提供的任何指导/建议。

谢谢!

【问题讨论】:

【参考方案1】:

我还没有使用过 Jest - 我通常使用 @angular 团队的默认设置 jasmine/karma - 但你不能使用 Testbed to configure it 吗?

使用 karma/jasmine,您可以执行以下操作:

beforeEach(async(() => 
TestBed.configureTestingModule(
    providers: [
        Http,
        InAppBrowser
    ],
)
));

beforeEach(async(() => TestUtils.beforeEachCompiler([]).then(compiled => 
    fixture = compiled.fixture;
    instance = compiled.instance;
    fixture.autoDetectChanges(true);

)));

【讨论】:

嗨克里斯蒂安-感谢您的贡献。我特意选择了 Jest,因为在 Ionic 项目中使用它的设置非常小/影响很小(查看了其他配置/安装 - 以及它们为比较奠定基础的复杂性 - 用于在内部使用不同的测试框架离子)。我没有在 Jest 的上下文中使用 Testbed 进行调查,但我绝对可以调查)

以上是关于在 Jest 测试框架中访问 Angular 服务构造函数的主要内容,如果未能解决你的问题,请参考以下文章

Jest 单元测试中的 Angular 循环依赖问题

前端angular基础测试篇

AG-Grid gridReady 未在使用 Angular 和 Jest 的测试中调用

在 sonarqube 中使用 jest 和旁观者覆盖组件方法的 Angular 打字稿测试

在 Angular 7 中使用 Jest 进行测试时缺少 Kendo Intl Service 的语言环境信息

Angular 5:如何在 Jest 测试中导入 jQuery?