是否可以为单元测试模拟自定义 Angular 2 Material SVG 图标?

Ben*_*min 6 unit-testing angular-material2 angular

在我的应用程序的根组件中,我为md-icon. 在对显示自定义图标的组件进行单元测试时,出现错误。似乎该错误可能是由于我的根组件没有在我的子单元测试中使用/初始化。

md-icon在设置测试模块时,有没有办法模拟或添加这些自定义图标(或)?我会简单地在我正在测试的组件中定义图标,但我知道其他组件也需要它们。

错误:

Uncaught Error: Error in ./CustomerComponent class CustomerComponent - inline template:34:19 caused by: __WEBPACK_IMPORTED_MODULE_4_rxjs_Observable__.Observable.throw is not a function
Run Code Online (Sandbox Code Playgroud)

完整错误: 在此处输入图片说明

从模板中删除自定义图标可以解决错误。


我的模板正在使用这样的自定义图标:

<md-icon svgIcon="vip">vip</md-icon>
Run Code Online (Sandbox Code Playgroud)

根组件像这样初始化图标:

this.iconRegistry.addSvgIcon(
    'vip',
    this.sanitizer.bypassSecurityTrustResourceUrl('assets/icons/vip.svg') as string,
);
Run Code Online (Sandbox Code Playgroud)

我像这样设置测试组件:

beforeEach(async(() => {
    TestBed.configureTestingModule({
        imports: [
            SharedModule,
            CoreModule,
            FormsModule,
            ReactiveFormsModule,
        ],
        providers: [
            {
                provide: Router,
                useClass: class {
                    navigate = jasmine.createSpy('navigate');
                },
            },
            {
                provide: ActivatedRoute,
                useValue: {
                    data: {
                        subscribe: (fn: (value: Data) => void) => fn({
                            customer: CUSTOMER,
                            company: COMPANY,
                        }),
                    },
                },
            },
            {
                provide: UtilityService,
                useClass: UtilityServiceMock,
            },
            // etc...
        ],
        declarations: [
            CustomerComponent,
        ],
        schemas: [
            CUSTOM_ELEMENTS_SCHEMA,
        ],
    })
    .compileComponents();
}));
Run Code Online (Sandbox Code Playgroud)

版本

  • 角 2.3.0
  • 材料 2.0.0-beta.1

Ben*_*min 3

回答我自己的问题:

经过多次尝试/错误(例如模拟MdIconRegistry或使用componentOverride()等)但没有运气,我不再在测试中使用共享模块。

相反,我使用类的模拟版本直接在测试模块中声明 MdIcon 组件。

describe(`CustomerComponent`, () => {
    let component: CustomerComponent;
    let fixture: ComponentFixture<CustomerComponent>;

    beforeEach(async(() => {
        TestBed.configureTestingModule({
            imports: [
                FormsModule,
                ReactiveFormsModule,
                MdButtonModule,
            ],
            providers: [
                OVERLAY_PROVIDERS,
                {
                    provide: Router,
                    useClass: class {
                        navigate = jasmine.createSpy('navigate');
                    },
                },
                {
                    provide: ActivatedRoute,
                    useValue: {
                        data: {
                            subscribe: (fn: (value: Data) => void) => fn({
                                customer: customer,
                                company: COMPANY,
                            }),
                        },
                        params: Observable.of({
                            customerId: customerId,
                        }),
                    },
                },
            ],
            declarations: [
                CustomerComponent,
                // Declare my own version of MdIcon here so that it is available for the CustomerComponent
                MdIconMock,
            ],
        });

        fixture = TestBed.createComponent(CustomerComponent);
        component = fixture.componentInstance;

        fixture.detectChanges();
    }));


    it(`should exist`, () => {    
        expect(component).toBeTruthy();
    });
});
Run Code Online (Sandbox Code Playgroud)

MdIconMock 只是一个与选择器匹配的空白类:

import { Component } from '@angular/core';

@Component({
    template: '',
    // tslint:disable-next-line
    selector: 'md-icon, mat-icon',
})
// tslint:disable-next-line
export class MdIconMock {
}
Run Code Online (Sandbox Code Playgroud)

注意:由于 TSLint 规则指定了类名/选择器的前缀/格式,我需要为此模拟禁用 TSLint。