Как написать тестовый блок Жасмин для комбайнаПоследний rxjs Angular - PullRequest
0 голосов
/ 29 ноября 2018

mycomponent.ts

import { Component, OnInit } from '@angular/core';
import {FormGroup,FormControl} from '@angular/forms'
import { DataServiceService } from './data-service.service';
import {combineLatest,Observable,pipe} from 'rxjs';
import {map,tap} from 'rxjs/operators';
import {Model} from './mode';
@Component({
  selector: 'my-app',
  templateUrl: './app.component.html',
  styleUrls: [ './app.component.css' ]
})
export class AppComponent  {

  constructor(private dataService: DataServiceService){}
  name = 'Angular';
  myForm: FormGroup;
  observableResult$: Observable<any>;

  ngOnInit(){
    this.myForm = new FormGroup({
      localId: new FormControl()
    })

  this.observableResult$ = combineLatest(
    this.myForm.get('localId').valueChanges,
    this.dataService.getDataFromURL(),
    (localIdSelected, dataFromAPI) => ({localIdSelected,dataFromAPI})).
    pipe(map(each => this.filterData(each.dataFromAPI,each.localIdSelected)));

    this.observableResult$.subscribe(value => {
      debugger
    })

  }
  filterData(dataFromAPI,localIDSelected){
    debugger
     return dataFromAPI.filter(item => item.userId > Number(localIDSelected));
    }

}

data.service.service.ts

import { Injectable } from '@angular/core';
import {HttpClient} from '@angular/common/http'
import {Model} from './mode';
import {Observable} from 'rxjs';
@Injectable()
export class DataServiceService {

  constructor(private http:HttpClient) { }

  getDataFromURL():Observable<Model>{
    return this.http.get<Model>('https://jsonplaceholder.typicode.com/todos');
  }

}

app.component.html

<form [formGroup]="myForm" >

<select formControlName="localId">
  <option>1</option>
  <option>2</option>
</select>

</form>

app.spec.ts

const spyFilter = spyOn(component as any, filterData).and.callThrough();

const constAPIData$ = staticDataServiceMock.getAPIData();
                    spyOn(staticDataServiceMock, 'getAPIData').and.returnValue(
                        observableOf(countryStaticData$)
                    );
component.myForm.get('localId').setValue(1);

component.observableResult$.subscribe(value => {
expect(value[0].id==21).toBeTrue();
});

staticDatamock.ts

export class StaticDataMock{

static getAPIData(): Observable<StaticDataElements[]> {
    return [
  {
    "userId": 1,
    "id": 1,
    "title": "delectus aut autem",
    "completed": false
  },
  {
    "userId": 1,
    "id": 2,
    "title": "quis ut nam facilis et officia qui",
    "completed": false
  },
  {
    "userId": 1,
    "id": 3,
    "title": "fugiat veniam minus",
    "completed": false
  },
  {
    "userId": 1,
    "id": 4,
    "title": "et porro tempora",
    "completed": true
  }];
  }
}

Я добавил свой тестовый пример, чтобы охватить оператор combLatest и filterData в app.spec.ts, но требуемый код не выполняется.и мое ожидание вызова filterData не удалось.combLatest запустит событие в valueChange и получит данные из API.я могу создать макет и setValue в файле спецификации, но он не работает.

1 Ответ

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

Хорошо, чтобы попытаться помочь вам в этом, я пошел дальше и создал Stackblitz с данными, которые вы предоставили до сих пор.Вот ссылка .

. Я сделал несколько вещей, чтобы тест заработал (вроде).

  • Я изменил тип метода getAPIData()в классе StaticDataMock для public, чтобы вы могли вызывать его извне класса.
  • У меня был метод, возвращающий of(), превращающий возвращаемое значение в Observable ваших данных.
  • Я догадывался о ваших реализациях насмешек DataServiceService, подробности в Stackblitz.
  • Я создал spyObject Jasmine, чтобы перехватывать вызовы getDataFromURL() в сервисе и возвращать наблюдаемые, которые вы создали с помощью StaticDataMock.
  • Я изменил порядок вызова вещей в спецификации и сделал console.log(), чтобы показать, что component.observableResult$ никогда не излучается.

Обновление

Согласно комментариям ниже, ссылка на Stackblitz выше была обновлена ​​и теперь работает.Из этого Stackblitz вот рабочая спецификация:

it('should change return of service.function1() only', () => {
    fixture.detectChanges(); 
    component.observableResult$.subscribe(value => {
        console.log('observable Emitted, value is ', value);
        expect(value[0].id==1).toBe(true); 
    });
    component.myForm.get('localId').setValue(1);
});

Ключом к этому было установить сначала подписку, а затем выдать новое значение в форме, которая обновит combineLatest() и выполниткод внутри subscribe().

Я рад, что это сработало!

...