在 Karma 中使用 PrimeNG 组件时出错

Error using PrimeNG component in Karma

嘿 whazzup 我的 (bk) stackerzzz。

我为你们准备了一个真正的好东西:

我在我的 angular 2 应用程序中使用来自 PrimeNG 库的 ConfirmDialog 组件。该组件在浏览器中测试时工作正常,但由于某种原因,使用该组件会使 Karma 爆炸。

 Error: Error in ./ReturnFileParameterComponent class ReturnFileParameterComponent - inline template:2:4 caused by: undefined is not a constructor (evaluating 'this.documentResponsiveListener()') in C:/Users/wlaw/Desktop/ens_fits_ui/karma-shim.js (line 41475)
        ngOnDestroy@C:/Users/wlaw/Desktop/ens_fits_ui/karma-shim.js:71991:45 <- webpack:///~/primeng/components/confirmdialog/confirmdialog.js:140:0
        ngOnDestroy
        destroyInternal
        destroy@C:/Users/wlaw/Desktop/ens_fits_ui/karma-shim.js:41076:34 <- webpack:///~/@angular/core/bundles/core.umd.js:12361:0
        ...

component.spec.ts 文件中,我导入了对话框组件工作所需的对话框服务和模块:

import {
    ...
    ConfirmDialogModule,
    ConfirmationService
} from 'primeng/primeng';


describe('Return File Parameter Component Test', () => {

    beforeEach(() => {
        TestBed.configureTestingModule({
            declarations: [ReturnFileParameterComponent, HtmlUserFriendlyTimePipe, Html24HourDatePipe, DayOfWeekPipe],
            providers: [
                ...
                ConfirmationService,
                ...
            ],
            imports: [
                ...
                ConfirmDialogModule
            ]
        });
        TestBed.compileComponents();
    });

...

    it('should call add on a new Return File Parameter and submit it to the service', inject(
        [ReturnFileParameterComponent, AuthHelper],
        (component: ReturnFileParameterComponent, authHelper: AuthHelper) => {
            let fixture: ComponentFixture<ReturnFileParameterComponent> =
                getTestBed().createComponent(ReturnFileParameterComponent);

            fixture.componentInstance.ngOnInit()
                .then(fixture.detectChanges)
                .then(function () {
                    let newParam = fixture.componentInstance.add();
                    expect(fixture.componentInstance.selectedParam).toBe(newParam);
                    expect(fixture.componentInstance.editParam).toBe(true);
                });
        })
    );
});

但几乎所有测试都失败了。

这是模板文件的开头部分:

<div class="ui-grid-row" id="return-parameter-table">
    <h5>Return File Parameters</h5>
    <p-growl [value]="msgs" life="3000"></p-growl>
    <p-confirmDialog header="Confirmation" icon="fa fa-question-circle" width="425"></p-confirmDialog>
...

所以基本上我不知道为什么它没有通过测试,但我在浏览器中使用它绝对没有问题。任何帮助将不胜感激。

好的,所以我找到了解决方法。 ConfirmDialogModule 模块声明的 ConfirmDialog 组件似乎在使用 Karma/Jasmine 时存在一些问题。所以我在规范中所做的是创建一个伪造的 ConfirmDialog 组件并覆盖 ConfirmDialogModule 模块中的元数据以查找伪造的组件。代码如下所示:

// Fake component class because the ConfirmDialog has issues with Karma/Jasmine
@Component({
    selector: 'p-confirmDialog',
    template: ''
})
class FakeConfirmDialogComponent {
}

describe('Return File Parameter Component Test', () => {

    beforeEach(() => {
        TestBed.configureTestingModule({
            declarations: [ReturnFileParameterComponent, HtmlUserFriendlyTimePipe, Html24HourDatePipe, DayOfWeekPipe],
            providers: [
                ...
                ConfirmationService,
                ...
            ],
            imports: [
                ConfirmDialogModule,
                ...
            ]
        });
        TestBed.overrideModule(ConfirmDialogModule, {
            set: {
                declarations: [FakeConfirmDialogComponent],
                exports: [FakeConfirmDialogComponent]
            }
        })
        TestBed.compileComponents();
    });

    // All my tests here
});

这里的关键部分是 TestBed.overrideModule() 方法调用,它修改了 ConfirmDialogModule 模块的元数据。