【问题标题】:Unit test that sequence of calls are made in order when the method called is the same but with different arguments (Jasmine & Angular)单元测试,当调用的方法相同但参数不同(Jasmine 和 Angular)时,调用顺序是按顺序进行的
【发布时间】:2021-01-07 08:38:41
【问题描述】:

我有一个 Angular 服务,该服务具有一个方法,该方法调用一个返回 observable 的 httpService 中的方法。 一旦该方法返回成功,就会对 httpService 的同一方法进行一系列并行调用,但使用不同的参数来保存一些图像。

我正在尝试对调用以正确的顺序和正确的参数进行单元测试。 当我尝试使用间谍和 .toHaveBeenCalled() 时,我只能得到 Jasmine 识别的第一个呼叫。

我假设它与时间有关,但我迷路了,找不到此用例的任何示例。任何指导将不胜感激。

编辑:代码 100% 工作,我的问题是如何为序列调用编写单元测试。

// 服务

// HttpS is a custom service that makes HTTP requests
constructor(private httpS: HttpS) {
}

save(params: {images: any[]}): Observable<any> {
   return this.saveEntry(params);
}

private saveEntry(params: {images: any[]}): Observable<any> {
  return this.httpS.put('url', {something: 'something'}).pipe(
    // once this request is successful, make parallel requests
    concatMap(() => {
      const reqs = [];
      params.images.forEach(image => {
        reqs.push(this.saveImage({ image }));
      });
    
      return forkJoin(reqs);
    })
  );
}

private saveImage(data: {image: any}): Observable<any> {
  return this.httpS.put('url',{imgData: data.image});
}

// 测试

describe('save', () => {

  it('should make a PUT request with something, then on success multiple parallel PUT requests with imgData', () => {

   spyOn(httpService, 'put').and.callFake(() => cold('-a|', { a: {} }));
   service.save(data).pipe(take(1)).subscribe();
   
   // The mock data I'm passing has 3 images so it results in 1 call first, then 3 in parallel, 1 for each image, but this test says it has been called just once.
   expect(httpS.put).toHaveBeenCalledTimes(4);

   // Trying .toHaveBeenCalledWith() but obviously that fails too

  })
})

【问题讨论】:

  • 在您的代码中 saveEntry 被通过 params 但它们未被接受。此外,没有定义images-iterable。这是复制粘贴事故还是您的实际实施?后者肯定能解释问题。
  • @PhilippMeissner 对此表示感谢。抱歉,我复制粘贴但删除了一些代码以避免不相关的混乱,但忘记了一些重要的部分。我应该澄清代码的工作原理,所以我确定代码本身没有任何问题,只是如何为它编写单元测试的问题。

标签: javascript angular unit-testing jasmine observable


【解决方案1】:

我认为这与 subscribe 的运行时间比您的断言晚(由于异步性质)有关。

试试这个:

describe('save', () => {

  it('should make a PUT request with something, then on success multiple parallel PUT requests with imgData', (done) => { // add done to tell Jasmine when you're done with unit test

   spyOn(httpService, 'put').and.callFake(() => cold('-a|', { a: {} }));
   service.save(data).pipe(take(1)).subscribe(response => {
     expect(httpS.put).toHaveBeenCalledTimes(4); // make assertion once the response comes back
     done(); // call done to let Jasmine know you're done with the test
   });
  
  })
})

【讨论】:

  • 非常感谢!这确实解决了这个问题。是否需要添加done()?是否只是让 Jasmine 不等待超时,从而使测试运行得更快?
  • 在这种情况下需要完成。等待超时将花费更长的时间并导致您的单元测试失败(未调用完成)并且未在回调中完成,由于订阅的异步性质,订阅内部的期望调用将不会运行。
猜你喜欢
  • 2015-03-17
  • 1970-01-01
  • 2019-09-14
  • 1970-01-01
  • 1970-01-01
  • 2018-09-04
  • 1970-01-01
  • 2021-06-06
  • 1970-01-01
相关资源
最近更新 更多