問題起因:
由於在Angular 的專案中開始使用 Dynamic Component Loader 來做一些頁面裡嵌入已經撰寫好、會重複使用的 component。但是在測試的時候反而遇到問題。
我測試的頁面只是一個很簡單的登入頁面,但是我的作法是 Lobby 頁面嵌入Login component而不是把Login整個寫在 Lobby裡面,由於使用Dynamic Component Loader就可以在使用者點擊『登入』時就把頁面中間載入Login component,點擊『註冊』時就載入Register component。
示意圖:
環境設定:
Ubuntu: 18.04.1 LTS
Angular Cli: 7.0.1
說明:
在Lobby component 中我在OnInit 中預設載入Login畫面,避免Lobby的內容區空空。
接著lobby.component.spec.ts 這支測試檔中主要程式碼如下:
describe('LobbyComponent', () => {
let component: LobbyComponent;
let fixture: ComponentFixture<LobbyComponent>;
beforeEach(async(() => { TestBed.configureTestingModule({ declarations: [ LobbyComponent, LoginComponent, GeneralRegisterComponent ], imports: [ ReactiveFormsModule ], providers: [ DynamicComponentService, ChangeMainContService ], entryComponents: [ LoginComponent, GeneralRegisterComponent, ] }) .compileComponents(); }));
beforeEach(() => { fixture = TestBed.createComponent(LobbyComponent); component = fixture.componentInstance; fixture.detectChanges(); });
it('should create', () => { expect(component).toBeTruthy(); });
it('should see login component in lobby page', async(() => { const lobbyComp = TestBed.createComponent(LobbyComponent); lobbyComp.detectChanges(); const compiled = lobbyComp.debugElement.nativeElement; expect(compiled.querySelector('#loginComp')).toBeTruthy(); })); });
beforeEach(async(() => { TestBed.configureTestingModule({ declarations: [ LobbyComponent, LoginComponent, GeneralRegisterComponent ], imports: [ ReactiveFormsModule ], providers: [ DynamicComponentService, ChangeMainContService ], entryComponents: [ LoginComponent, GeneralRegisterComponent, ] }) .compileComponents(); }));
beforeEach(() => { fixture = TestBed.createComponent(LobbyComponent); component = fixture.componentInstance; fixture.detectChanges(); });
it('should create', () => { expect(component).toBeTruthy(); });
it('should see login component in lobby page', async(() => { const lobbyComp = TestBed.createComponent(LobbyComponent); lobbyComp.detectChanges(); const compiled = lobbyComp.debugElement.nativeElement; expect(compiled.querySelector('#loginComp')).toBeTruthy(); })); });
這邊大概說明一下由於使用Dynamic Component Loader要在你的@NgModule內加入 entryComponents: [] 讓loader 知道要載入哪些Components。所以很理所當然在測試檔中生成測試module的 TestBed.configureTestingModule({}) 加入entryComponents的內容。
不過加上去之後跑ng test的時候就會出現下面的錯誤。而且vscode在你填入那段程式的時候就已經幫你畫下紅線跟你說有問題。
ng cli 錯誤資訊:
瀏覽器的錯誤資訊:
明明加了entryCompnents但是好像不認得!最後在Overflow上面可以使用overriderModule的方式改寫TestBed.configureTestingModule()的內容,但是這邊記得要
import { BrowserDynamicTestingModule } '@angular/platform-browser-dynamic/testing'
而另一種寫法我比較喜歡😅 就是把要TestBed要產生的Testing Module 獨立寫在上方的NgModule內,程式碼就會變成如下:
這樣比較清楚有架構而且測試檔也能正常執行。
不過加上去之後跑ng test的時候就會出現下面的錯誤。而且vscode在你填入那段程式的時候就已經幫你畫下紅線跟你說有問題。
ng cli 錯誤資訊:
瀏覽器的錯誤資訊:
明明加了entryCompnents但是好像不認得!最後在Overflow上面可以使用overriderModule的方式改寫TestBed.configureTestingModule()的內容,但是這邊記得要
import { BrowserDynamicTestingModule } '@angular/platform-browser-dynamic/testing'
而另一種寫法我比較喜歡😅 就是把要TestBed要產生的Testing Module 獨立寫在上方的NgModule內,程式碼就會變成如下:
@NgModule({
declarations: [
LobbyComponent,
LoginComponent,
GeneralRegisterComponent,
],
imports: [
ReactiveFormsModule
],
providers: [
DynamicComponentService,
ChangeMainContService
],
entryComponents: [
LoginComponent,
GeneralRegisterComponent
]
})
class FakeEntryComponents { }
describe('LobbyComponent', () => { let component: LobbyComponent; let fixture: ComponentFixture<LobbyComponent>;
beforeEach(async(() => { TestBed.configureTestingModule({ imports: [ FakeEntryComponents ] }) .compileComponents(); }));
beforeEach(() => { fixture = TestBed.createComponent(LobbyComponent); component = fixture.componentInstance; fixture.detectChanges(); });
it('should create', () => { expect(component).toBeTruthy(); });
it('should see login component in lobby page', async(() => { const lobbyComp = TestBed.createComponent(LobbyComponent); lobbyComp.detectChanges(); const compiled = lobbyComp.debugElement.nativeElement;< expect(compiled.querySelector('#loginComp')).toBeTruthy(); })); });
describe('LobbyComponent', () => { let component: LobbyComponent; let fixture: ComponentFixture<LobbyComponent>;
beforeEach(async(() => { TestBed.configureTestingModule({ imports: [ FakeEntryComponents ] }) .compileComponents(); }));
beforeEach(() => { fixture = TestBed.createComponent(LobbyComponent); component = fixture.componentInstance; fixture.detectChanges(); });
it('should create', () => { expect(component).toBeTruthy(); });
it('should see login component in lobby page', async(() => { const lobbyComp = TestBed.createComponent(LobbyComponent); lobbyComp.detectChanges(); const compiled = lobbyComp.debugElement.nativeElement;< expect(compiled.querySelector('#loginComp')).toBeTruthy(); })); });
這樣比較清楚有架構而且測試檔也能正常執行。
留言
張貼留言