[英]How to test an angular service promise call?
我有一个服务SmsService
,它在我组件的SmsService
submit()
方法内返回一个承诺。
在我的组件中,我从this.sms.send()
调用this.sms.send()
方法, then()
追加then()
和catch()
: this.sms.send(this.messageInput).then(....).catch(....)
的断言expect(smsSpy.send).toHaveBeenCalledWith(component.messageInput)
正常工作,后this.sms.send()
被调用,但是this.messageInput
不重置为空,并且断言失败。 我究竟做错了什么? 我没有正确运行变更检测吗?
我试图编写一些测试,以确保分别根据我的send()
间谍返回的Promise调用then
和catch
在我的组件中。 我该怎么办? 。
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import {MomentModule} from 'angular2-moment'
import { FormsModule } from '@angular/forms';
import { AngularFirestore } from '@angular/fire/firestore';
import { Observable, of } from "rxjs";
import { ActivatedRoute } from '@angular/router';
import {SmsService} from './sms.service'
//my component
import {
Component,
OnInit,
AfterViewChecked,
ViewChild,
ElementRef,
AfterViewInit
} from "@angular/core";
@Component({
selector: "app-sms",
templateUrl: "./sms.component.pug",
styleUrls: ["./sms.component.scss"]
})
export class SmsComponent {
@ViewChild("scrollMe") private myScrollContainer: ElementRef;
public messageInput;
public list;
public err;
constructor(public sms: SmsService, private route:ActivatedRoute) {
this.list = this.sms.getItems()//this.route.data['value']['messages']
}
submit() {
this.sms
.send(this.messageInput)
.then(res => {
// console.log(res);
this.messageInput = null
})
.catch(err => {
this.err = `Could not send - ${err}`
});
}
}
//my test
describe('SmsComponent', () => {
let component: SmsComponent;
let fixture: ComponentFixture<SmsComponent>;
var afSpy = jasmine.createSpyObj('AngularFirestore', ['collection', 'valueChanges', 'snapshotChanges', 'pipe', 'add']);
var smsSpy = jasmine.createSpyObj('SmsService', ['send', 'then','catch']);
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [ SmsComponent ],
providers:[
{ provide: SmsService, useValue: smsSpy },
{ provide: AngularFirestore, useValue: afSpy },
{
provide: ActivatedRoute, useValue: {
params: of([{ id: 'test' }])
}
}
],
imports:[MomentModule, FormsModule],
})
.compileComponents();
}));
beforeEach(() => {
fixture = TestBed.createComponent(SmsComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('expect err', () => {
smsSpy.send.and.returnValue(Promise.resolve('asdf'));
smsSpy.catch.and.returnValue('caught');
component.messageInput = 'my new message'
component.submit()
fixture.detectChanges();
expect(smsSpy.send).toHaveBeenCalledWith(component.messageInput) //<-- this passes
expect(component.messageInput).toBe(null) //<---- this fails
});
});
您的服务没有任何then
或catch
方法。 它只有一个send()
方法,该方法返回Promise。 返回的Promise是具有then和catch方法的对象。 因此,这一行毫无意义:
var smsSpy = jasmine.createSpyObj('SmsService', ['send', 'then','catch']);
您需要使间谍返回承诺,并且需要控制异步,例如通过使用fakeAsync()
。
这是一个几乎与您匹配的完整示例(我只保留了重要部分):
零件:
import { Component } from '@angular/core';
import { SmsService } from '../sms.service';
@Component({
selector: 'app-sms',
templateUrl: './sms.component.html',
styleUrls: ['./sms.component.scss']
})
export class SmsComponent {
public messageInput: string;
constructor(private sms: SmsService) { }
submit() {
this.sms
.send(this.messageInput)
.then(res => {
this.messageInput = null;
});
}
}
测试:
import { fakeAsync, TestBed, tick } from '@angular/core/testing';
import { SmsComponent } from './sms.component';
import { SmsService } from '../sms.service';
describe('SmsComponent', () => {
let component: SmsComponent;
beforeEach(() => {
TestBed.configureTestingModule({
declarations: [ SmsComponent ]
});
});
beforeEach(() => {
component = TestBed.createComponent(SmsComponent).componentInstance;
});
it('should sublut and clear', fakeAsync(() => {
// obtain the service injected in the component by Angular
const smsService: SmsService = TestBed.get(SmsService);
// spy on its send method, and make it return a resolved promise
spyOn(smsService, 'send').and.returnValue(Promise.resolve('hello world'));
// set the message input in the component
component.messageInput = 'world';
// call submit()
component.submit();
// check that the service call has been made
expect(smsService.send).toHaveBeenCalledWith('world');
// tick in order to trigger the execution of the then callback registered on the promise
tick();
// check that the callback has rset the messageInput to null
expect(component.messageInput).toBeNull();
}));
});
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.