无法测试在茉莉花中使用Observable的方法

时间:2018-11-21 22:26:01

标签: angular6 angular-testing

我的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的{​​{1}}方法。到目前为止,我写的BackendService是以下内容,但我认为这是不正确的,因为收到spec的模拟响应时,控制台上没有看到任何打印内容。

createQuestion

1 个答案:

答案 0 :(得分:0)

问题是我正在创建一个Observable,但没有使用Observer将值推入next。正确的实现是(代码段)

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

在创建Observable时,Rxjs中的Observable的构造函数将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个方法nexterrorcomplete的对象。请注意,subscribe函数采用这样的对象

(res)=>{... },
    (error:ServerResponseAPI)=>{
     ...
    },
    ()=>{ //observable complete
        ...
      })