невозможно проверить метод, который использует Observable в Жасмин - PullRequest
0 голосов
/ 22 ноября 2018

Мое Angular приложение имеет службу QuestionManagementService, которая отвечает на BackendService для отправки REST сообщений.BackendService в свою очередь использует HttpClient.Я пытаюсь проверить QuestionManagementService в изоляции.

Метод, который я тестирую, addQuestion

addQuestion(question:PracticeQuestion):any{
    console.log("In QuestionManagementService: addQuestion: ",question);
   this.bs.createQuestion(question).subscribe((res)=>{
      console.log("add practice question - response is ",res);//I EXPECT THESE PRINTS TO SHOW BUT THEY DON'T
      let ev = <HttpEvent<any>>(res);
      if(ev.type === HttpEventType.Response) {
        console.log('response from server: returning body '+ev.body);
        let isResponseStructureOK: boolean = this.helper.validateServerResponseStructure(ev.body);
        if (isResponseStructureOK) {
          let response:ServerResponseAPI = ev.body;
          console.log("received response from server: " + response.result);
          this.addQuestionSubject.next(new Result(response.result,response['additional-info']));

        } else {
          console.log("received incorrect response structure from server: ", ev.body);
          this.addQuestionSubject.next(new Result('error','Invalid response structure from server'));

        }
      }
      else {
        console.log("not response. ignoring");
      }
    },
    (error:ServerResponseAPI)=>{
      console.log("got error from the Observable: ",error);
      let errorMessage:string = this.helper.userFriendlyErrorMessage(error);
      this.addQuestionSubject.next(new Result('error',errorMessage));//TODOM - need to standardise errors

    },
    ()=>{ //observable complete
        console.log("observable completed")
      });
  }

Поскольку я выполняю модульное тестирование addQuestion, я подумал, что могу высмеять метод createQuestion BackendService.spec, который я написал до сих пор, является следующим, но я не думаю, что это правильно, поскольку я не вижу никаких отпечатков на консоли, когда получен поддельный ответ createQuestion.

fit('should add a question',()=>{
    let backendService = TestBed.get(WebToBackendInterfaceService);
    let questionService = TestBed.get(QuestionManagementService);
    let question = new PracticeQuestion(...);

    const responseData = { result: 'success', ['additional-info']: 'question added successfully' };
    let httpResponseEvent:HttpResponse<any> = new HttpResponse<any>({body:responseData});
    //mock response of WebToBackendInterfaceService
    spyOn(backendService,'createQuestion').and.returnValue(new Observable(()=>{
      httpResponseEvent;
    }));

    questionService.addQuestion$.subscribe((res:Result)=>{
      console.log('received response from Question Services',res);
      expect(res).toBeTruthy();
      let validResponse:boolean = ((res.result === 'success') || (res.result === 'initial')) ;
      expect(validResponse).toEqual(true);
    });
    questionService.addQuestion(question);
    expect(backendService.createQuestion).toHaveBeenCalled();
  });

1 Ответ

0 голосов
/ 22 ноября 2018

Проблема заключалась в том, что я создавал Observable, но я не выдвигал значение до Observer, используя next.Правильная реализация (фрагмент кода)

        spyOn(backendService,'createQuestion').and.returnValue(new Observable((subscriber)=>{ //subscriber or observer
      subscriber.next(httpResponseEvent)}
    ));

При создании Observable конструктор Observable в Rxjs принимает функцию subscribe в качестве аргумента.Определение функции subscribe:

(observer)=>{
/*logic of calculating values which Observer should produce and emit then using observer.next(value)*/
}

, ссылка - http://reactivex.io/rxjs/class/es6/Observable.js~Observable.html

. При использовании приведенного выше кода this.bs.createQuestion(question) возвращает макет Observable, функция subscribe которого равна

(subscriber)=>{ //subscribe function 
          subscriber.next(httpResponseEvent)
}

Вышеуказанная функция subscribe будет вызываться всякий раз, когда любой Observer подписывается на Observable.Поэтому в коде .subscribe((res)=>{...} я подписываюсь на макет Observable, и теперь функция subscribe будет выдавать фиктивное значение, httpResponseEvent для моего кода.Для новичков в Observables функция subscribe принимает Observer в качестве аргумента.Observer - это объект, который имеет 3 метода next, error и complete.Обратите внимание, что функция subscribe принимает такой объект

(res)=>{... },
    (error:ServerResponseAPI)=>{
     ...
    },
    ()=>{ //observable complete
        ...
      })
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...