Как проверить угловой сервис обещания вызова? - PullRequest
0 голосов
/ 13 декабря 2018

У меня есть служба SmsService, которая возвращает обещание в методе submit() в моем компоненте.

В моем компоненте я вызываю метод this.sms.send() из SmsService и добавляю then() & catch(): this.sms.send(this.messageInput).then(....).catch(....)

Утверждение expect(smsSpy.send).toHaveBeenCalledWith(component.messageInput) работает правильно после вызова this.sms.send(), однако this.messageInput не сбрасывается в ноль и это утверждение не выполняется.Что я делаю неправильно?Я не запускаю обнаружение изменений должным образом?

Я пытаюсь написать пару тестов, чтобы гарантировать, что then и catch внутри моего компонента будут вызываться в зависимости от обещания, возвращенного моим send() шпионом.Как бы я это сделал?,

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

1 Ответ

0 голосов
/ 13 декабря 2018

Ваш сервис не имеет метода then или catch.Он имеет только метод send(), который возвращает Обещание.Возвращенный 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();
  }));
});
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...