gpt4 book ai didi

Angular2 单元测试不使用模拟服务

转载 作者:行者123 更新时间:2023-12-02 15:09:05 25 4
gpt4 key购买 nike

我正在测试一个显示/隐藏登录/退出按钮的非常简单的组件。

为此,我模拟了我的 AuthService 服务,因为它依赖于 AngularFire2。

我遇到的问题是我的模拟服务 (Mock AuthService) 似乎没有被提供来代替实际的 AuthService

在测试中应该显示 Facebook 登录按钮service.isAnonymous 应该是未定义的。在实际服务中,确实如此。但在模拟服务中是 true。这个测试应该会失败。

另外,请注意我正在尝试调用方法 service.test(false);;在模拟服务中,此方法存在并且是public。但是我收到错误:

Property 'test' does not exist on type '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;
}
}

我不知道如何提供模拟。

更新:

根据目前的答案和评论,我更新了我的模拟测试规范。但是,我仍然遇到同样的问题。

我收到错误消息Property 'test' does not exist on type 'AuthService'。

这表明它仍然没有用模拟代替实际的 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');
}));
});

最佳答案

beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [ FacebookLoginComponent ],
// providers: [{ provide: AuthService, useValue: MockAuthService }]
})
.compileComponents();

TestBed.overrideComponent(FacebookLoginComponent, {
set: {
providers: [{ provide: AuthService, useClass: MockAuthService }]
}
})
}));

有两个问题。您不需要覆盖组件的提供程序,因为您可以在配置 TestBed 时提供它们。

我假设您已经开始覆盖组件,因为初始配置不起作用。它不起作用,因为您使用的是 useValue 而不是 useClass

  // providers: [{ provide: AuthService, useValue: MockAuthService }]

应该这样做:

beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [ FacebookLoginComponent ],
providers: [{ provide: AuthService, useClass: MockAuthService }]
}).compileComponents();
}));

编辑:

当使用inject 函数时,您应该使用MockAuthService 作为类型。 TypeScript 应该停止提示。

inject([ AuthService ], (service: MockAuthService) => { /* ... */ });

关于Angular2 单元测试不使用模拟服务,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44985957/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com