2017-02-20 88 views
3

在新的ng cli項目中基本使用md-sidenav-container會導致ng測試在第二次和後續測試中失敗。Angular2 Material md-sidenav-container在ng測試中導致異常

異常

TypeError: Cannot read property 'unsubscribe' of undefined 
     at ScrollDispatcher.deregister (webpack:///~/@angular/material/core/overlay/scroll/scroll-dispatcher.js:52:0 <- src/test.ts:10756:50) 
     at Scrollable.ngOnDestroy (webpack:///~/@angular/material/core/overlay/scroll/scrollable.js:28:0 <- src/test.ts:86637:22) 
     at Wrapper_Scrollable.ngOnDestroy (/OverlayModule/Scrollable/wrapper.ngfactory.js:13:16) 
     at CompiledTemplate.proxyViewClass.View_MdSidenavContainer0.destroyInternal (/MdSidenavModule/MdSidenavContainer/component.ngfactory.js:66:24) 
     at CompiledTemplate.proxyViewClass.AppView.destroy (webpack:///~/@angular/core/src/linker/view.js:203:0 <- src/test.ts:82496:14) 
     at CompiledTemplate.proxyViewClass.DebugAppView.destroy (webpack:///~/@angular/core/src/linker/view.js:606:0 <- src/test.ts:82899:38) 
     at CompiledTemplate.proxyViewClass.View_AppComponent0.destroyInternal (/DynamicTestModule/AppComponent/component.ngfactory.js:115:19) 
     at CompiledTemplate.proxyViewClass.AppView.destroy (webpack:///~/@angular/core/src/linker/view.js:203:0 <- src/test.ts:82496:14) 
     at CompiledTemplate.proxyViewClass.DebugAppView.destroy (webpack:///~/@angular/core/src/linker/view.js:606:0 <- src/test.ts:82899:38) 
     at CompiledTemplate.proxyViewClass.View_AppComponent_Host0.destroyInternal (/DynamicTestModule/AppComponent/host.ngfactory.js:33:19) 
     at CompiledTemplate.proxyViewClass.AppView.destroy (webpack:///~/@angular/core/src/linker/view.js:203:0 <- src/test.ts:82496:14) 
     at CompiledTemplate.proxyViewClass.DebugAppView.destroy (webpack:///~/@angular/core/src/linker/view.js:606:0 <- src/test.ts:82899:38) 
     at CompiledTemplate.proxyViewClass.AppView.detachAndDestroy (webpack:///~/@angular/core/src/linker/view.js:187:0 <- src/test.ts:82480:14) 
     at ComponentRef_.destroy (webpack:///~/@angular/core/src/linker/component_factory.js:147:51 <- src/test.ts:40464:70) 
     at ComponentFixture.destroy (webpack:///~/@angular/core/bundles/core-testing.umd.js:263:0 <- src/test.ts:21186:35) 

app.component.html

<div> 
    <md-sidenav-container> 
    <md-sidenav mode="side" opened="true">Drawer content</md-sidenav> 
    <div class="my-content">Main content</div> 
    </md-sidenav-container> 
</div> 

app.component.spec.ts

import {TestBed, async} from '@angular/core/testing'; 
import {MaterialModule} from '@angular/material'; 
import {AppComponent} from './app.component'; 
import 'hammerjs'; 

describe('AppComponent',() => { 
    beforeEach(() => { 
    TestBed.configureTestingModule({ 
     imports: [ 
     MaterialModule 
     ], 
     declarations: [ 
     AppComponent 
     ], 
    }); 
    TestBed.compileComponents(); 
    }); 

    it('should create the app', async(() => { 
    const fixture = TestBed.createComponent(AppComponent); 
    const app = fixture.debugElement.componentInstance; 
    expect(app).toBeTruthy(); 
    })); 

    // Same test repeated enough to generate exception 
    it('should create the app', async(() => { 
    const fixture = TestBed.createComponent(AppComponent); 
    const app = fixture.debugElement.componentInstance; 
    expect(app).toBeTruthy(); 
    })); 
}); 

的package.json(默認+材料2.0.0-beta.2)

{ 
    "name": "admin", 
    "version": "0.0.0", 
    "license": "MIT", 
    "angular-cli": {}, 
    "scripts": { 
    "start": "ng serve", 
    "lint": "tslint \"src/**/*.ts\"", 
    "test": "ng test", 
    "pree2e": "webdriver-manager update", 
    "e2e": "protractor" 
    }, 
    "private": true, 
    "dependencies": { 
    "@angular/common": "^2.4.0", 
    "@angular/compiler": "^2.4.0", 
    "@angular/core": "^2.4.0", 
    "@angular/forms": "^2.4.0", 
    "@angular/http": "^2.4.0", 
    "@angular/platform-browser": "^2.4.0", 
    "@angular/platform-browser-dynamic": "^2.4.0", 
    "@angular/material": "^2.0.0-beta.2", 
    "@angular/router": "^3.4.0", 
    "core-js": "^2.4.1", 
    "rxjs": "^5.0.1", 
    "ts-helpers": "^1.1.1", 
    "zone.js": "^0.7.2" 
    }, 
    "devDependencies": { 
    "@angular/cli": "1.0.0-beta.31", 
    "@angular/compiler-cli": "^2.4.0", 
    "@types/jasmine": "2.5.38", 
    "@types/node": "^6.0.42", 
    "codelyzer": "~2.0.0-beta.1", 
    "jasmine-core": "2.5.2", 
    "jasmine-spec-reporter": "2.5.0", 
    "karma": "1.2.0", 
    "karma-chrome-launcher": "^2.0.0", 
    "karma-cli": "^1.0.1", 
    "karma-jasmine": "^1.0.2", 
    "karma-coverage-istanbul-reporter": "^0.2.0", 
    "protractor": "~5.1.0", 
    "ts-node": "1.2.1", 
    "tslint": "^4.3.0", 
    "typescript": "~2.0.0" 
    } 
} 

app.component.ts

import {Component, ElementRef, OnInit} from '@angular/core'; 
import {HostListener} from '@angular/core/src/metadata/directives'; 
import {AuthService} from './services/auth.service'; 
import {ConceptService} from './services/concept.service'; 
import {AppService} from './services/app.service'; 
import {Router, NavigationStart} from '@angular/router'; 
import {LocationService} from './services/location.service'; 
import {ConfigService} from './services/config.service'; 
import {ToastService} from './services/toast.service'; 
import {ContextService} from './services/context.service'; 

@Component({ 
    selector: 'app-root', 
    templateUrl: 'app.component.html', 
    styleUrls: ['app.component.css'], 
}) 

export class AppComponent implements OnInit { 
    sidenavOpen = true; 
    appElement; 
    envName = 'default'; 
    _serverVersion: any = '{}'; 
    currentRoute = ''; 

    menuItems = [ 
    {route: 'home', name: 'Dashboard', icon: 'home'} 
    // some lines omitted 
    , {route: 'concepts', name: 'Concepts', icon: 'toc'} 

    ]; 


    constructor(elementRef: ElementRef, 
       private authService: AuthService, 
       private conceptService: ConceptService, 
       private configService: ConfigService, 
       private locationService: LocationService, 
       private appService: AppService, 
       private contextService: ContextService, 
       private toast: ToastService, 
       private router: Router) { 
    this.appElement = elementRef.nativeElement; 
    } 

    ngOnInit(): void { 
    this.appService.container = this.appElement.querySelector('.app-content'); 
    // Warm caches 
    Promise.all([ 
     this.conceptService.getAll(), 
     this.configService.getAll(), 
     this.locationService.getAll(), 
     this.configService.serverVersion().then(ver => this._serverVersion = ver), 
     this.contextService.getContext().then(ctx => this.envName = ctx.name.replace(' ', '_').toLowerCase()) 
    ]).catch(e => this.toast.error(e)); 

    // Monitor size for handling sidebar 
    this.onResize(this.appElement.clientWidth); 
    this.router.events.subscribe((event) => { 
     if (event instanceof NavigationStart) { 
     this.onResize(this.appElement.clientWidth); 
     } 
    }); 

    // Log out on closing or or navigating away 
    window.onbeforeunload = function() { 
     this.authService.logout(); 
    }.bind(this); 
    } 

    @HostListener('window:resize', ['$event.target.innerWidth']) 
    onResize(w) { 
    this.sidenavOpen = w > 500; 
    } 

    isDisabled(path: string) { 
    return !this.authService.isAuthorised(path); 
    } 
} 
+0

你能發佈你的AppComponent代碼嗎? –

+0

,我也看到這一點,可能是要在github – nPn

+0

這最後的評論提請注意你的問題,傑西報告的錯誤。我不知道我怎麼錯過了它的時間。我已經加入我的App.component.ts到我的職務。 (我恢復到2.0.0-beta.1來避免這個問題。) –

回答

0

我也有同樣的問題。我通過爲燈具等製作全球vars來解決它。

fdescribe('AppComponent',() => { 
    let component: AppComponent; 
    let fixture: ComponentFixture<AppComponent>; 
    let de: DebugElement; 
    let el: HTMLElement; 


beforeEach(() => { 
TestBed.configureTestingModule({ 
    declarations: [ 
    AppComponent 
    ], 
    imports:[RouterModule,UiPageHeaderModule,UiAppHeaderModule,RouterTestingModule, MaterialModule.forRoot()], 
}); 
TestBed.compileComponents(); 
}); 

    it('should create the app', async(() => { 
const app = fixture.debugElement.componentInstance; 
expect(app).toBeTruthy(); 
})); 

    // Same test repeated enough to generate exception 
    it('should create the app', async(() => { 
    //const fixture = TestBed.createComponent(AppComponent); no need of this. this is causing the issue, 
    const app = fixture.debugElement.componentInstance; 
    expect(app).toBeTruthy(); 
    })); 
});