【发布时间】:2018-04-24 19:58:42
【问题描述】:
我正在尝试测试一个基本上具有电子邮件和密码字段的组件。一旦填写了这两个字段,用户就可以单击按钮并向服务器发送请求。当我通过浏览器测试这个组件时,它会执行我想要的行为。但是当我使用规范文件测试组件时,subscribe 方法永远不会执行(obs:我在模拟服务)。这是组件的onSubmit 方法:
onSubmit(formAuthentication: NgForm) {
if (this.credential.email == undefined || this.credential.password == undefined) {
this.error = "Preencha o campo de email e de senha para continuar"
return;
} else {
this.tokenManagerService.generateNewToken(this.credential);
this.tokenManagerService.retrieveToken().subscribe(token => {
console.log(token);
const tokenRetrieved = JSON.parse(token);
if (tokenRetrieved.error) {
this.error = tokenRetrieved.error;
} else {
foo();
}
});
formAuthentication.resetForm();
}
}
这是规范文件和测试本身的配置:
describe('AuthenticationComponent', () => {
let component: AuthenticationComponent;
let fixture: ComponentFixture<AuthenticationComponent>;
let inputEmail: HTMLInputElement;
let inputPassword: HTMLInputElement;
let loginButton: HTMLInputElement;
let tokenManagerServiceMock: TokenManagerServiceMock;
let mockRouter = {
navigate: jasmine.createSpy('navigate')
}
beforeEach(() => {
tokenManagerServiceMock = new TokenManagerServiceMock();
TestBed.configureTestingModule({
declarations: [ AuthenticationComponent ],
imports: [ FormsModule, HttpModule,RouterTestingModule.withRoutes([]) ],
providers: [
{ provide: TokenManagerService, useValue: tokenManagerServiceMock }
]
});
TestBed.overrideComponent(AuthenticationComponent, {
set: {
providers: [
{ provide: TokenManagerService, useValue: tokenManagerServiceMock }
]
}
});
fixture = TestBed.createComponent(AuthenticationComponent)
fixture.componentInstance.ngOnInit();
tokenManagerServiceMock = TestBed.get(TokenManagerService);
fixture.detectChanges();
inputEmail = fixture.debugElement.nativeElement.querySelector('input[type=text]');
inputPassword = fixture.debugElement.nativeElement.querySelector('input[type=password]');
loginButton = fixture.nativeElement.querySelector('input[type=submit]');
});
it('should detect white field message',() => {
fixture.whenStable().then(() => {
inputEmail.value = faker.internet.email();
inputEmail.dispatchEvent(new Event('input'));
inputPassword.value = faker.internet.password();
inputPassword.dispatchEvent(new Event('input'));
loginButton.click();
fixture.detectChanges();
});
});
});
我可能做错了什么?
EDIT 1:我很确定subscribe 方法永远不会执行,因为在subscribe 方法内部,如果有一个名为token.error 的节点,组件应该设置一个错误要在此块中显示的变量:
<div class="error-block" *ngIf="error">
<h6>{{ error }}</h6>
</div>
但这条消息从未出现在因果报应中。
编辑 2: 这是我的 mockService 来模拟原来的认证服务:
import { Injectable } from '@angular/core';
import { Credential } from '../models/credential';
import { AuthenticationService } from './authentication.service'
import { Observable } from 'rxjs/Observable';
import { Subject } from 'rxjs/Subject';
import * as token from 'rand-token';
@Injectable()
export class TokenManagerServiceMock {
private tokenKey: string = 'codeToken';
private subject = new Subject<any>();
constructor() {}
public generateNewToken(credential: Credential): void {
let currentTime:number = (new Date()).getTime();
if (credential.email == 'eminetto@coderockr.com') {
const data = token.suid(24);
this.subject.next(JSON.stringify({ttl: currentTime, data}));
} else {
const error = 'Usuário ou senha inválidos';
this.subject.next(JSON.stringify({ttl: currentTime, error}));
}
}
public retrieveToken(): Observable<string> {
console.log('achieved retrieve');
return this.subject.asObservable();
}
}
【问题讨论】:
-
请提供您在测试中调试的细节
'should detect white field message',以便其他人可以尝试提供帮助。 (例如,您如何知道它没有执行订阅等) -
@DanielWSrimpel 那里有一个
console.log并且永远不会被执行 -
再次,请提供详细信息,准确说明您遇到的情况以及到目前为止您为调试问题所做的工作(在您的问题中提供)
-
您能否提供有关您的
TokenManagerServiceMock类的详细信息,以显示它如何模拟在测试中的类(AuthenticationComponent)中使用的方法(generateNewToken(...)、retrieveToken(...))? -
尝试在模拟类中将
Subject更改为BehaviorSubject
标签: angular angular-cli karma-jasmine