为什么我的单元测试通过Chrome并且使用PhantomJS失败?

Sef*_*nio 4 phantomjs karma-runner angular-cli angular angular-test

我正在使用Angular2 final(2.0.2)和angular-cli.我正在尝试将其设置为使用PhantomJS运行单元测试.使用Chrome和karma-chrome-launcher运行规范 - 所有测试都通过.运行相同的Phantomjs-prebuilt 2.1.13和karma-phantomjs-launcher 1.0.2测试失败.

我将phantomjs启动器添加到karma.conf中的plugins数组,以及浏览器数组中的PahntomJS.

我得到的错误是:

PhantomJS 2.1.1(Mac OS X 0.0.0)DataTableFormat应以毫秒为单位转换日期FAILED ReferenceError:找不到变量:src/main/js/test.ts中的Intl(第53565行)intlDateFormat @ webpack:/// Users /sninio/dev/csp-ui/~/@angular/common/src/facade/intl.js:117:0 < - src/main/js/test.ts:53565:20 webpack:/// Users/sninio /dev/csp-ui/~/@angular/common/src/facade/intl.js:148:36 < - src/main/js/test.ts:53596:59 dateFormatter @ webpack:/// Users/sninio /dev/csp-ui/~/@angular/common/src/facade/intl.js:157:0 < - SRC /主/ JS/test.ts:53605:39格式@的WebPack:///用户/ sninio /dev/csp-ui/~/@angular/common/src/facade/intl.js:192:0 < - SRC /主/ JS/test.ts:53640:29变换@的WebPack:///用户/ sninio /dev/csp-ui/~/@angular/common/src/pipes/date_pipe.js:92:0 < - SRC /主/ JS/test.ts:70473:90变换@的WebPack:///用户/ sninio /dev/csp-ui/src/main/js/app/pages/+platform/events/data-table/data-table.pipe.ts:9:4418 < - src/main/js/test.ts:52698 :5787 webpack:/// Users/sninio/dev/csp-ui/src/main/js/app/pages/+ platform/events /data-table/data-table.pipe.spec.ts:20:30 < - src/main/js/test.ts:60923:30执行@ webpack:/// Users/sninio/dev/csp-ui/~/@angular/core/bundles/core-testing.umd.j < - src/main/js/test.ts:2997:28 webpack:/// Users/sninio/dev/csp-ui /〜/ @ angular /core/bundles/core-testing.umd.js:951:32 < - src/main/js/test.ts:3084:56调用@ webpack:/// Users/sninio/dev/csp-ui /〜/ zone.js/dist/zone.js:203:0 < - src/main/js/test.ts:98886:33 onInvoke @ webpack:///Users/sninio/dev/csp-ui/~/zone.js /dist/proxy.js:72:0 < - src/main/js/test.ts:68790:45调用@ webpack:///Users/sninio/dev/csp-ui/~/zone.js/dist/ zone.js:202:0 < - src/main/js/test.ts:98885:42运行@ webpack:///Users/sninio/dev/csp-ui/~/zone.js/dist/zone.js :96:0 < - SRC /主/ JS/test.ts:98779:49的WebPack:///Users/sninio/dev/csp-ui/~/zone.js/dist/jasmine-patch.js:91: 27 < - SRC /主/ JS/test.ts:68526:53执行@的WebPack:///Users/sninio/dev/csp-ui/~/zone.js/dist/jasmine-patch.js:119:0 < - src/main/js/test.ts:68554:46执行@ webpack:///Users/sninio/dev/csp-ui/~/zone.js/dist/jasmin 电子patch.js:119:0 < - SRC /主/ JS/test.ts:68554:46 invokeTask @的WebPack:///Users/sninio/dev/csp-ui/~/zone.js/dist/zone .js:236:0 < - src/main/js/test.ts:98919:42 runTask @ webpack:///Users/sninio/dev/csp-ui/~/zone.js/dist/zone.js: 136:0 < - src/main/js/test.ts:98819:57 drainMicroTaskQueue @ webpack:///Users/sninio/dev/csp-ui/~/zone.js/dist/zone.js:368:0 < - src/main/js/test.ts:99051:42 PhantomJS 2.1.1(Mac OS X 0.0.0)DataTableFormat应该转换日期字符串FAILED

也许我在angular-cli创建的test.ts文件中缺少一些配置?

更新: 看来,失败的进口唯一的测试DatePipeJsonPipe.
我也试图导入@angular/common/testing,test.ts但这没有帮助 - 它们不会在相关的index.js中导出.
也尝试导入整个,@angular/common/pipes但也没有用.

这是管道:

import { Pipe, PipeTransform } from "@angular/core";
import { DatePipe, JsonPipe } from "@angular/common";

@Pipe({name: 'dataTableFormat'})
export class DataTablePipe implements PipeTransform {

    // values with type 'json' are parsed to json. As a result, string values may be displayed with quotes ("<string>").
    // To avoid that, we remove these quotes with this regex
    private quotesExp: RegExp = /^\"|\"$/gi;

    constructor(private datePipe: DatePipe, private jsonPipe: JsonPipe) {

    }

    transform(value: any, type: string): string {
        switch (type) {
            case "date":
                return this.datePipe.transform(value, 'short');
            case "json":
                return this.jsonPipe.transform(value).replace(this.quotesExp, "");
            default:
                return value;
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

和规格:

import { inject, TestBed } from "@angular/core/testing";
import { DataTablePipe } from "./data-table.pipe";
import { DatePipe, JsonPipe } from "@angular/common";

describe('DataTableFormat', () => {

    beforeEach(() => {
        TestBed.configureTestingModule({
            providers: [
                DatePipe, JsonPipe
            ]
        });

    });

    it('should transform date in milliseconds', inject([DatePipe, JsonPipe], (datePipe, jsonPipe) => {
        let pipe = new DataTablePipe(datePipe, jsonPipe);
        let testDate: Date = new Date();

        expect(pipe.transform(testDate.getTime(), 'date')).toBe(datePipe.transform(testDate, 'short'));
    }));

    it('should transform date string', inject([DatePipe, JsonPipe], (datePipe, jsonPipe) => {
        let pipe = new DataTablePipe(datePipe, jsonPipe);
        let testDate: Date = new Date();

        expect(pipe.transform(testDate.toISOString(), 'date')).toBe(datePipe.transform(testDate, 'short'));
    }));

    it('should transform json', inject([DatePipe, JsonPipe], (datePipe, jsonPipe) => {
        let pipe = new DataTablePipe(datePipe, jsonPipe);
        let testJson = {
            prop1: "val1",
            prop2: "val2"
        };

        expect(pipe.transform(testJson, 'json')).toBe(jsonPipe.transform(testJson));
    }));

});
Run Code Online (Sandbox Code Playgroud)

这是我的test.ts文件 - 没有改变它产生的那个angular-cli...

import "./polyfills.ts";
import "zone.js/dist/long-stack-trace-zone";
import "zone.js/dist/proxy.js";
import "zone.js/dist/sync-test";
import "zone.js/dist/jasmine-patch";
import "zone.js/dist/async-test";
import "zone.js/dist/fake-async-test";


// Unfortunately there's no typing for the `__karma__` variable. Just declare it as any.
declare var __karma__: any;
declare var require: any;

// Prevent Karma from running prematurely.
__karma__.loaded = function () {
};

//noinspection TypeScriptUnresolvedVariable
Promise.all([
    System.import('@angular/core/testing'),
    System.import('@angular/platform-browser-dynamic/testing'),
    System.import('../../../node_modules/nvd3/build/nv.d3.min.js'),
])
// First, initialize the Angular testing environment.
    .then(([testing, testingBrowser]) => {
        testing.getTestBed().initTestEnvironment(
            testingBrowser.BrowserDynamicTestingModule,
            testingBrowser.platformBrowserDynamicTesting()
        );
    })
    // Then we find all the tests.
    .then(() => require.context('./', true, /\.spec\.ts/))
    // And load the modules.
    .then(context => context.keys().map(context))
    // Finally, start Karma to run the tests.
    .then(__karma__.start, __karma__.error);
Run Code Online (Sandbox Code Playgroud)

知道为什么这适用于Chrome而不是PhantomJS?

Sef*_*nio 12

由于PhantomJS没有Intl实现Angular2所依赖的实现,解决方案是安装npm package intl polyfill并编辑polyfills.ts包含

import 'intl';
import 'intl/locale-data/jsonp/en.js';
Run Code Online (Sandbox Code Playgroud)

请看这里:https
://github.com/angular/angular/issues/3333
这里:https://github.com/angular/angular/issues/10809和这里:https://coryrylan.com/blog/adding-在-国际化,填充工具到一个棱角-CLI-项目

  • 这很酷,但是因为你专门为PhantomJS填充,我建议你将导入,包括你依赖的其他语言环境添加到`test.ts`文件中. (2认同)