Jasmine SpyOn订阅未执行下一个呼叫

时间:2020-09-14 15:12:18

标签: javascript angular jasmine

我正试图监视我的订阅,但似乎无法弄清楚该如何做。该方法本身看起来像这样:

list.service.ts

@Injectable({providedIn: 'root'})
export class ListService {

  public constructor(
    private readonly queryBuilderService: QueryBuilderService
  ) {}

  public paginate() {
    this.paginator = this.queryBuilderService
      .table('a') // Returns instance of QueryBuilder.ts
      .firstPage();
 
    this.paginator.$pagination.subscribe(() => {
      window.scroll(0, 0);
    });
    return this.paginator;
  }
}

firstPage()方法执行查询并返回当前对象,然后我们用$pagination监听变化,它们看起来像这样:

QueryBuilder.ts -注意:这不是服务。

export class QueryBuilder {
  private readonly paginationBehavior: Subject<any> = new Subject<any>();
  public $pagination = this.paginationBehavior.asObservable();

  public firstPage() {
    // Do stuff then execute query
    return this;
  }
}

因此,现在要创建我的测试用例,我在firstPage()上创建一个间谍并返回QueryBuilder的实例,该实例调用next()。我等了一会儿,但它从未执行我创建的窗口间谍。

  it('should paginate', fakeAsync(() => {
    const httpClient = TestBed.inject(HttpClient);
    const spy = spyOn(window, 'scroll');

    const queryBuilder = QueryBuilder.prototype;
    const queryBuilderInstance = new QueryBuilder(new GraphQLClientService(httpClient));

    spyOn(queryBuilder, 'firstPage').and.callFake(() => {
      queryBuilderInstance['paginationBehavior'].next({
        count: 1,
        isFirstPage: true,
        isLastPage: false,
        page: 1,
        pages: 1,
        results: [],
        total: 1
      });
      return queryBuilderInstance;
    });

    service.paginate();
    tick(1000);
    expect(spy).toHaveBeenCalled();
  }));

2 个答案:

答案 0 :(得分:0)

当我们使用AngularJSstub promisesSpyOn中编写测试时,我们做了类似的事情:

spyOn(someService,'get').and.returnValue(deferred.promise);

上面的代码是完全有效的-与observables不同,promises始终是异步的。但是如何测试Observables? 使用 jasmine-marbles 是灵魂之一。

有关observables测试的更多信息,请参见以下文章:

Testing Observables in Angular

How to test Observables

答案 1 :(得分:0)

对我来说似乎有效的解决方法是将setTimeout放入firstPage间谍中以模仿网络请求,然后订阅paginate()方法的响应。 / p>

  it('should paginate', async(inject([HttpClient], (httpClient: HttpClient) => {
    const spy = spyOn(window, 'scroll');

    const queryBuilderInstance = new QueryBuilder(new GraphQLClientService(httpClient));

    spyOn(QueryBuilder.prototype, 'firstPage').and.callFake(() => {
      setTimeout(() =>
        queryBuilderInstance['paginationBehavior'].next({
          count: 1,
          isFirstPage: true,
          isLastPage: false,
          page: 1,
          pages: 1,
          results: [],
          total: 1
        })
        , 10);
      return queryBuilderInstance;
    });

    service.paginate().$pagination.subscribe(() => {
      expect(spy).toHaveBeenCalled();
    });
  })));