Jon*_*tes 2 unit-testing karma-jasmine angular
我正在测试一个非常简单的组件,它显示/隐藏登录/退出按钮。
\n\n为此,我嘲笑我的AuthService服务,因为它依赖于 AngularFire2。
我遇到的问题是,似乎Mock AuthService没有提供我的模拟服务 () 来代替实际的AuthService.
在测试中should show the Facebook login button,service.isAnonymous预计是未定义的。实际服务中确实如此。但在模拟服务中是true。这个测试应该会失败。
另外,请注意我正在尝试调用该方法service.test(false);;在模拟服务中,此方法存在并且是public。但我收到错误:
\n\n\n类型“AuthService”上不存在属性“test”。
\n
这表明我的模拟服务没有被提供。
\n\n您可以在我的测试规范中看到我如何尝试两种方式来提供模拟服务(其中一种已被注释掉):
\n\nimport { DebugElement } from '@angular/core';\nimport {\n async,\n inject,\n ComponentFixture,\n TestBed\n} from '@angular/core/testing';\nimport { By } from '@angular/platform-browser';\n\nimport { FacebookLoginComponent } from './facebook-login.component';\nimport { AuthService } from '../shared/auth.service';\nimport { MockAuthService } from '../shared/testing/auth.service';\n\ndescribe('FacebookLoginComponent', () => {\n let authService: AuthService;\n let component: FacebookLoginComponent;\n let fixture: ComponentFixture<FacebookLoginComponent>;\n let debugElement: DebugElement;\n let htmlElement: HTMLElement;\n\n beforeEach(async(() => {\n TestBed.configureTestingModule({\n declarations: [ FacebookLoginComponent ],\n // providers: [{ provide: AuthService, useValue: MockAuthService }]\n })\n .compileComponents();\n\n TestBed.overrideComponent(FacebookLoginComponent, {\n set: {\n providers: [{ provide: AuthService, useClass: MockAuthService }]\n }\n })\n }));\n\n beforeEach(() => {\n fixture = TestBed.createComponent(FacebookLoginComponent);\n component = fixture.componentInstance;\n fixture.detectChanges();\n });\n\n it('should be created', () => {\n expect(component).toBeTruthy();\n });\n\n it('should show the Facebook login button', inject([ AuthService ], (service: AuthService) => {\n expect(service.isAnonymous).toBeUndefined();\n\n debugElement = fixture.debugElement.query(By.css('button'));\n htmlElement = debugElement.nativeElement;\n\n service.test(false);\n\n expect(htmlElement.textContent).toBe('Facebook Login');\n }));\n\n it('should show the Logout button', () => {\n debugElement = fixture.debugElement.query(By.css('button'));\n htmlElement = debugElement.nativeElement;\n\n expect(htmlElement.textContent).toBe('Logout');\n });\n});\nRun Code Online (Sandbox Code Playgroud)\n\n为了完整性;这是我的模拟服务MockAuthService:
import { Injectable } from '@angular/core';\n\n@Injectable()\nexport class MockAuthService {\n public authState: { isAnonymous: boolean, uid: string };\n\n constructor() {\n this.authState = { isAnonymous: true, uid: '0HjUd9owxPZ5kibvUCN6S2DgB4x1' };\n }\n\n // public get currentUser(): firebase.User {\n // return this.authState ? this.authState : undefined;\n // }\n\n // public get currentUserObservable(): Observable<firebase.User> {\n // return this.afAuth.authState;\n // }\n\n public get currentUid(): string {\n return this.authState ? this.authState.uid : undefined;\n }\n\n public get isAnonymous(): boolean {\n return this.authState ? this.authState.isAnonymous : false;\n }\n\n public get isAuthenticated(): boolean {\n return !!this.authState;\n }\n\n // public logout(): void {\n // this.afAuth.auth.signOut();\n // }\n\n public test(isAnonymous: boolean) {\n this.authState.isAnonymous = isAnonymous;\n }\n}\nRun Code Online (Sandbox Code Playgroud)\n\n我不知道如何提供模拟。
\n\n根据到目前为止的答案和评论,我已经更新了我的模拟测试规范。但是,我仍然遇到同样的问题。
\n\n我收到错误“AuthService”类型上不存在属性“test”。
\n\n这表明它仍然没有用模拟来代替实际authService服务。
此外,当我添加:
\n\npublic test(test: boolean): boolean {\n return test;\n}\nRun Code Online (Sandbox Code Playgroud)\n\n到实际服务测试失败;但不是因为上面的错误,而是因为它应该 \xe2\x80\x94 未满足测试的期望。
\n\n这是我更新的规格:
\n\nimport { DebugElement } from '@angular/core';\nimport {\n async,\n inject,\n ComponentFixture,\n TestBed\n} from '@angular/core/testing';\nimport { By } from '@angular/platform-browser';\n\nimport { FacebookLoginComponent } from './facebook-login.component';\nimport { AuthService } from '../shared/auth.service';\nimport { MockAuthService } from '../shared/testing/auth.service';\n\ndescribe('FacebookLoginComponent', () => {\n let authService: AuthService;\n let component: FacebookLoginComponent;\n let fixture: ComponentFixture<FacebookLoginComponent>;\n let debugElement: DebugElement;\n let htmlElement: HTMLElement;\n\n beforeEach(async(() => {\n TestBed.configureTestingModule({\n declarations: [ FacebookLoginComponent ],\n providers: [{ provide: AuthService, useClass: MockAuthService }]\n }).compileComponents();\n }));\n\n beforeEach(() => {\n fixture = TestBed.createComponent(FacebookLoginComponent);\n component = fixture.componentInstance;\n fixture.detectChanges();\n });\n\n it('should be created', () => {\n expect(component).toBeTruthy();\n });\n\n it('should show the Facebook Login button', inject([ AuthService ], (service: AuthService) => {\n debugElement = fixture.debugElement.query(By.css('button'));\n htmlElement = debugElement.nativeElement;\n\n expect(htmlElement.textContent).toBe('Facebook Login');\n }));\n\n it('should show the Logout button', inject([ AuthService ], (service: AuthService) => {\n expect(service.isAnonymous).toBe(true);\n\n debugElement = fixture.debugElement.query(By.css('button'));\n htmlElement = debugElement.nativeElement;\n\n service.test(false);\n\n fixture.detectChanges();\n\n expect(htmlElement.textContent).toBe('Logout');\n }));\n});\nRun Code Online (Sandbox Code Playgroud)\n
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [ FacebookLoginComponent ],
// providers: [{ provide: AuthService, useValue: MockAuthService }]
})
.compileComponents();
TestBed.overrideComponent(FacebookLoginComponent, {
set: {
providers: [{ provide: AuthService, useClass: MockAuthService }]
}
})
}));
Run Code Online (Sandbox Code Playgroud)
有两个问题。您不需要覆盖组件的提供程序,因为您可以在配置TestBed.
我假设您已经开始覆盖该组件,因为初始配置不起作用。它不起作用,因为您已经使用useValue了useClass.
// providers: [{ provide: AuthService, useValue: MockAuthService }]
Run Code Online (Sandbox Code Playgroud)
这应该做:
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [ FacebookLoginComponent ],
providers: [{ provide: AuthService, useClass: MockAuthService }]
}).compileComponents();
}));
Run Code Online (Sandbox Code Playgroud)
编辑:
使用inject函数时,应将其用作MockAuthService类型。TypeScript 应该停止抱怨。
inject([ AuthService ], (service: MockAuthService) => { /* ... */ });
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
4703 次 |
| 最近记录: |