繁体   English   中英

如何测试角度服务承诺电话?

[英]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调用thencatch在我的组件中。 我该怎么办?

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
  });
});

您的服务没有任何thencatch方法。 它只有一个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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM