2016-12-15 33 views
0

我有在Angular2文本組件了一個問題,我收到以下錯誤,當我試圖運行的TestRunner:前compileComponents變量運行Angular2測試設置

Component: Product Component Should ensure component subscribes to service EventEmitter on instantiation 
Failed: Cannot read property 'detectChanges' of undefined 
TypeError: Cannot read property 'detectChanges' of undefined 
Component: Product Component Should check that service getProducts is called when component getProducts is called 
Failed: Cannot read property 'getProducts' of undefined 
TypeError: Cannot read property 'getProducts' of undefined 

這裏是我的測試模塊:

import { ProductService } from "../../../../services/product.service"; 
import { TestBed, ComponentFixture, async } from "@angular/core/testing"; 
import { ProductComponent } from "../../../../components/catalog/products/ProductComponent"; 
import { HttpModule } from "@angular/http"; 
import { DebugElement, CUSTOM_ELEMENTS_SCHEMA } from "@angular/core"; 
import { Observable } from "rxjs/Rx"; 

class MockProductService { 
    emitter = Observable.of({}); 
    constructor() { 

    } 

    getProducts() { 
     return this; 
    } 
} 

let comp: ProductComponent; 
let fixture: ComponentFixture<ProductComponent>; 
let de:  DebugElement; 
let el:  HTMLElement; 

describe('Component: Product Component',() => { 
    let mockProductService; 

    beforeEach(() => { 
     mockProductService = new MockProductService(); 

     TestBed.configureTestingModule({ 
      declarations: [ 
       ProductComponent 
      ], 
      providers: [ 
       { 
        provide: ProductService, useValue: mockProductService 
       } 
      ], 
      imports: [ 
       HttpModule 
      ], 
      schemas: [CUSTOM_ELEMENTS_SCHEMA] 
     }) 
     .compileComponents() 
      .then(() => { 
       fixture = TestBed.createComponent(ProductComponent); 
       comp = fixture.componentInstance; 
      }); 
    }); 

    it('Should ensure component subscribes to service EventEmitter on instantiation',() => { 
     // TestBed.compileComponents() 
      //.then(() => { 
       //spyOn(mockProductService, 'emitter').and.returnValue({ 
       // subscribe:() => {} 
       //}); 


       fixture.detectChanges(); 
       fixture.whenStable().then(() => { 
        expect(comp.products).toBe({}); 
       }); 
       //expect(mockProductService.emitter).toHaveBeenCalled(); 
      //}); 
    }); 

    it('Should check that service getProducts is called when component getProducts is called',() => { 

     //TestBed.compileComponents() 
     // .then(() => { 

       spyOn(mockProductService, 'getProducts').and.returnValue({ 
        subscribe:() => {} 
       }); 

       comp.getProducts({}); 
       expect(mockProductService.getProducts).toHaveBeenCalled(); 
     // }); 
    }); 


}); 

由於被測組件使用通過類的templateUrl屬性的外部模板,所以我必須使用TestBed的compileComponents方法來編譯該模板以準備測試。正如你可以看到的那樣,在調用回來之後,我會重新定義一個承諾,然後爲每個測試定義fixture和組件實例。因爲這是在beforeEach這將爲每個測試完成。

當我試圖從我的測試中訪問燈具和組件實例時,它說它們是未定義的,這導致我相信在從compileComponents方法返回promise之前調用了測試。我試着將TestBed.CompileComponents移動到每個測試規範中,但這也會導致錯誤。

任何人都可以提醒我需要改變嗎? 謝謝

回答

2

我已經成功地使用了以下兩種方法。要麼使用DoneFn推遲對beforeEach,直到一切都完成了:

beforeEach(done => { 
    mockProductService = new MockProductService(); 

    TestBed.configureTestingModule({ 
     ... 
    }) 
    .compileComponents() 
     .then(() => { 
      fixture = TestBed.createComponent(ProductComponent); 
      comp = fixture.componentInstance; 
      done(); 
     }); 
}); 

或者使用async和分裂beforeEach分爲兩部分:

beforeEach(async(() => { 
    mockProductService = new MockProductService(); 

    TestBed.configureTestingModule({ 
     ... 
    }) 
    .compileComponents(); 
})); 

beforeEach(() => { 
    fixture = TestBed.createComponent(ProductComponent); 
    comp = fixture.componentInstance; 
}); 
+0

或'fakeAsync',而不是'async' – yurzui

+0

這似乎工作,但我改變它到這個代碼後,我得到這個錯誤。好像spyOn getProducts不起作用並返回訂閱函數來模擬對象。 :TypeError:this._productService.getProducts(...)。subscribe不是函數 – devoncrazylegs

+0

@devoncrazylegs這是一個單獨的問題。我會嘲笑,如http://stackoverflow.com/a/39376968/3001761 – jonrsharpe

相關問題