我正在測試一個顯示/隱藏登錄/退出按鈕的非常簡單的組件。Angular2單元測試不使用模擬服務
爲此我嘲笑我的AuthService
服務,因爲它依賴於AngularFire2。
我遇到的問題是出現我的模擬服務(Mock AuthService
)沒有被提供來代替實際的AuthService
。
在測試should show the Facebook login button
,service.isAnonymous
預計未定義。在實際的服務中,它是。但在模擬服務是true
。這個測試應該失敗。
另外,請注意我正在嘗試調用方法service.test(false);
;在模擬服務中,此方法存在並且是public
。但是我收到錯誤:類型'AuthService'上不存在屬性「測試」。
這表明我的模擬服務沒有提供。
你可以看到我是如何嘗試了兩種方式,在我的測試規範提供模擬服務(一個被註釋掉):
import { DebugElement } from '@angular/core';
import {
async,
inject,
ComponentFixture,
TestBed
} from '@angular/core/testing';
import { By } from '@angular/platform-browser';
import { FacebookLoginComponent } from './facebook-login.component';
import { AuthService } from '../shared/auth.service';
import { MockAuthService } from '../shared/testing/auth.service';
describe('FacebookLoginComponent',() => {
let authService: AuthService;
let component: FacebookLoginComponent;
let fixture: ComponentFixture<FacebookLoginComponent>;
let debugElement: DebugElement;
let htmlElement: HTMLElement;
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [ FacebookLoginComponent ],
// providers: [{ provide: AuthService, useValue: MockAuthService }]
})
.compileComponents();
TestBed.overrideComponent(FacebookLoginComponent, {
set: {
providers: [{ provide: AuthService, useClass: MockAuthService }]
}
})
}));
beforeEach(() => {
fixture = TestBed.createComponent(FacebookLoginComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should be created',() => {
expect(component).toBeTruthy();
});
it('should show the Facebook login button', inject([ AuthService ], (service: AuthService) => {
expect(service.isAnonymous).toBeUndefined();
debugElement = fixture.debugElement.query(By.css('button'));
htmlElement = debugElement.nativeElement;
service.test(false);
expect(htmlElement.textContent).toBe('Facebook Login');
}));
it('should show the Logout button',() => {
debugElement = fixture.debugElement.query(By.css('button'));
htmlElement = debugElement.nativeElement;
expect(htmlElement.textContent).toBe('Logout');
});
});
爲了完整;這裏是我的模擬服務,MockAuthService
:
import { Injectable } from '@angular/core';
@Injectable()
export class MockAuthService {
public authState: { isAnonymous: boolean, uid: string };
constructor() {
this.authState = { isAnonymous: true, uid: '0HjUd9owxPZ5kibvUCN6S2DgB4x1' };
}
// public get currentUser(): firebase.User {
// return this.authState ? this.authState : undefined;
// }
// public get currentUserObservable(): Observable<firebase.User> {
// return this.afAuth.authState;
// }
public get currentUid(): string {
return this.authState ? this.authState.uid : undefined;
}
public get isAnonymous(): boolean {
return this.authState ? this.authState.isAnonymous : false;
}
public get isAuthenticated(): boolean {
return !!this.authState;
}
// public logout(): void {
// this.afAuth.auth.signOut();
// }
public test(isAnonymous: boolean) {
this.authState.isAnonymous = isAnonymous;
}
}
我不知道如何提供模擬代替。
更新:根據答案和評論到目前爲止我有更新我的模擬測試規範
。但是,我仍然有同樣的問題。
我得到錯誤類型'AuthService'上不存在屬性'test'。
這表明它仍然沒有用實際的authService
服務替代模擬。
而且,當我添加:
public test(test: boolean): boolean {
return test;
}
給實際的服務測試失敗;但不是因爲上面的錯誤,而是因爲它應該 - 測試的期望沒有得到滿足。
這是我的最新規範:
import { DebugElement } from '@angular/core';
import {
async,
inject,
ComponentFixture,
TestBed
} from '@angular/core/testing';
import { By } from '@angular/platform-browser';
import { FacebookLoginComponent } from './facebook-login.component';
import { AuthService } from '../shared/auth.service';
import { MockAuthService } from '../shared/testing/auth.service';
describe('FacebookLoginComponent',() => {
let authService: AuthService;
let component: FacebookLoginComponent;
let fixture: ComponentFixture<FacebookLoginComponent>;
let debugElement: DebugElement;
let htmlElement: HTMLElement;
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [ FacebookLoginComponent ],
providers: [{ provide: AuthService, useClass: MockAuthService }]
}).compileComponents();
}));
beforeEach(() => {
fixture = TestBed.createComponent(FacebookLoginComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should be created',() => {
expect(component).toBeTruthy();
});
it('should show the Facebook Login button', inject([ AuthService ], (service: AuthService) => {
debugElement = fixture.debugElement.query(By.css('button'));
htmlElement = debugElement.nativeElement;
expect(htmlElement.textContent).toBe('Facebook Login');
}));
it('should show the Logout button', inject([ AuthService ], (service: AuthService) => {
expect(service.isAnonymous).toBe(true);
debugElement = fixture.debugElement.query(By.css('button'));
htmlElement = debugElement.nativeElement;
service.test(false);
fixture.detectChanges();
expect(htmlElement.textContent).toBe('Logout');
}));
});
這是一個類,而不是一個值; 'useClass:MockAuthService'或'useValue:new MockAuthService()'。 – jonrsharpe
謝謝@jonrsharpe,儘管我仍然遇到這個問題,但我已經更新了測試規範。請看我更新的問題。 –
如果你訪問'(service作爲MockAuthService).test'會怎麼樣? – jonrsharpe