被监视的方法没有被调用-预期的间谍显示已被调用

时间:2018-11-14 17:28:27

标签: jasmine angular6

我有一个sendMessage方法,该方法调用了另一个服务(LoaderServiceshow方法。

sendMessage(url:string, body:any,httpOptions):Observable<HttpEvent<any>> {
    this.loaderService.show();
  ... //IT DOES OTHER THINGS AS WELL BUT THAT ISN'T WHAT I AM TESTING
}

我正在尝试测试是否调用了show方法,但是出现了错误Expected spy show to have been called.。我可能做错了什么?我认为show应该被调用,因为它是sendMessage的第一行。

spec

describe('sendMessage function test suite: ',()=> {
  let loader: LoaderService;
  let httpClient:HttpClient;
  let spy:any;
  const httpOptions = {
    headers: new HttpHeaders({'Content-Type': 'application/json'}),
    withCredentials: true,
    observe: 'events',
    responseType: 'json'
  };


  beforeEach(() => {
    TestBed.configureTestingModule({
      providers: [HelperService, HttpClient, HttpHandler,LoaderService],
      imports: [ReactiveFormsModule, HttpClientModule, HttpClientTestingModule]
    });
  });

  fit('should show loader/spinner',
      inject([HttpTestingController,HelperService,HttpClient,LoaderService],(httpClient:HttpClient,httpMock:HttpTestingController)=>{
      const responseData = { result: 'success', ['additional-info']: 'some data from server' };

      loader = new LoaderService();
      spyOn(loader,'show'); //sendMessage calls show method of loader.
      let httpEvent:HttpResponse<any> = new HttpResponse<any>({body:responseData});    
      let helperService = TestBed.get(HelperService);
      let result:Observable<HttpEvent<any>> = helperService.sendMessage('/someURL','someBody',httpOptions);
      let subscription = result.subscribe((event:HttpEvent<any>)=>{
        console.log('got response ',event);
      });
      expect(loader.show).toHaveBeenCalled(); 
  }));
});

2 个答案:

答案 0 :(得分:0)

您监视LoaderService的另一个 实例。 spyOn函数用于将间谍程序安装到对象中,而不是全局安装。

您可以获得使用HelperService注入到TestBed.get(LoaderService)的实例。

请参阅此Testing - Component with a dependency文档。

答案 1 :(得分:0)

上面的Mixth解释是正确的。以下是我的看法,我认为我应该分享。

我想我以前的代码做错了几件事。据我了解,我可以通过3种方式进行测试

1)仅使用Jasmine和Karma,而不使用Testbed。这是一种通用方法。我用这种方法显式创建所需的类的实例。例如。

new LoaderService()

以上对于我自己定义的类(服务和组件)非常有效。但是,如果我的测试用例使用了某些Angular的模块(例如HttpClientModule),那么最好使用TestBed-“测试床是Angular的一项非常特定的功能,它将负责实例化组件,服务并负责使用DI的依赖项”

为确保测试用例始终都在引用一个类的同一实例,应在所有类的TestBed个实例中使用extract

fit('should show loader/spinner',()=>{
    let helperService = TestBed.get(HelperService);//extract helper service
    let loaderService = TestBed.get(LoaderService);//extract Loader Service. As I am using TestBed, I'll get the same instance of LoaderService which Angular would have used to create HelperrService
    spyOn(loaderService,'show'); //sendMessage calls hide method of loader.

    const responseData = { result: 'success', ['additional-info']: 'some data from server' };
    let httpEvent:HttpResponse<any> = new HttpResponse<any>({body:responseData});
/*HttpTestingController to be injected into tests, that allows for mocking and flushing of requests.
HttpTestingController has methods which could mock sending a request
 */
    let httpMock = TestBed.get(HttpTestingController);
    //call the sendMessage function and subscribe to its observable.
    let result:Observable<HttpEvent<any>> = helperService.sendMessage('/someURL','someBody',httpOptions);
    let subscription = result.subscribe((event:HttpEvent<any>)=>{
      console.log('got response ',event);
    });
    const mockReq:TestRequest = httpMock.expectOne('/someURL'); //Expect that a single request has been made which matches the given URL, and return its mock
    //once mocking of sending request is done, mock receiving a response. This will trigger the logic inside subscribe function
    mockReq.flush(httpEvent); //flush method provides dummy values as response

    httpMock.verify();//verify checks that there are no outstanding requests;

    expect(loaderService.show).toHaveBeenCalled(); //check that the loader show is called which in real application will show a progress bar
  });