【问题标题】:Component creation fails in jasmine test茉莉花测试中的组件创建失败
【发布时间】:2017-02-28 12:46:16
【问题描述】:

鉴于以下订阅 observable 的组件(在应用程序中运行良好),尝试通过 jasmine/karma 创建组件时失败。

未捕获的错误:./MappingComponent 类 MappingComponent 中的错误 - 内联模板:0:5 原因:无法读取属性“mapCursorClass” 未定义的 在 ViewWrappedError.ZoneAwareError (http://localhost:9876/base/src/test.ts:84141:33)

这与他的可观察性有关。如果这只是一个字符串,那就不用麻烦了:

    /**
     * Container component that composes the mapping toolbar (pan, zoom, drag, draw, measure etc)
     * and the mapping provider (underlying 3rd party mapping display engine - Leaflet, OpenLayers etc)
    */
    @Component({
        selector: 'mapping-component',
        //templateUrl: './mapping.component.html',
        template: '<div [ngClass]="mapCursorClass | async"></div>',
        styleUrls: ['./mapping.component.css']
    })
    export class MappingComponent extends events.EventEmitter {
        mapContainerElementId = "map-container";
        private mapCursorClass : Observable<string>;

        constructor(
            MappingProviders.MappingProvider,
            public mappingProvider: LeafletMappingProvider,
            private store: Store<fromRoot.State>,
            private mapLayerService: MapLayerService,
            private organisationService: OrganisationService,
            private projectService: ProjectService
        ) {
            super();


            this.mapCursorClass = this.store.select(fromRoot.getMapCursor); // bound to the html
        }

和规格:

describe('MappingComponent',
    () => {
        let component: MappingComponent;
        let fixture: ComponentFixture<MappingComponent>;

        // Add the imported module to the imports array in beforeEach 
        beforeEach(async(() => {
            TestBed.configureTestingModule({
                imports: [
                        AppModule,
                        StoreModule.provideStore({})
                    ]//,
                    //declarations: [MappingComponent]
                })
                .compileComponents();

        }));

        beforeEach(() => {
            fixture = TestBed.createComponent(MappingComponent);
            component = fixture.componentInstance;
            fixture.detectChanges();
        });

        it('should create',
            () => {
                expect(component).toBeTruthy();
            });
    });

【问题讨论】:

  • 为什么你的 TestBed 中的组件声明被注释掉了?
  • @Jason Lutz AppModule 将其拉入...

标签: angular rxjs karma-jasmine ngrx


【解决方案1】:

原来是这个问题

StoreModule.provideStore({})

正如它所期望的 @ngrx/store reducer,AppModule 实际上是这样做的:

import { reducer } from './app.reducer';
...
imports: [
        BrowserModule,
        FormsModule,
        HttpModule,
        /**
         * StoreModule.provideStore is imported once in the root module, accepting a reducer
         * function or object map of reducer functions. If passed an object of
         * reducers, combineReducers will be run creating your application
         * meta-reducer. This returns all providers for an @ngrx/store
         * based application.
        */
        StoreModule.provideStore(reducer),

从夹具中删除该行是修复(或者我可以重新引入组件,使用正确的减速器修复该行并删除 AppModule 导入):

    beforeEach(async(() => {
        TestBed.configureTestingModule({
            imports: [
                StoreModule.provideStore(reducer)
            ],
            declarations: [MappingComponent]
        })
        .compileComponents();

    }));

【讨论】:

  • 一般来说,您应该尝试采用第二种方法,这样您就不会在单元测试中导入整个应用程序模块。我跳过了您最初是在导入它。采用这种方法的好处在于,您可以模拟所有您不关心的服务,并专注于测试您的组件。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2015-12-13
  • 1970-01-01
  • 1970-01-01
  • 2015-01-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多