0

我是 javascript 测试的新手,我找不到明确的例子来学习如何测试这些方法。我显然需要一些帮助!

这是我正在尝试测试的两种方法:

public _getSearch(search: Search): Observable < any[] > {
    const timeOptions: DateCriteria = this._getTimeStartEnd(search);
    const searchField: string = this._decodeHexIfNecessary(search.searchField.trim());

    return this.store.pipe(
            select(getFilterById(search.filterId)),
            flatMap((filter: Filter) => {

                const indicators = [{
                        'criterias': this.filterService.getActiveCriterias(filter)
                    }
                ];
                search.lastSearch = new TransactionRequest(
                        search.offset, search.pageSize, timeOptions.begin, timeOptions.end,
                        indicators, search.sortData, searchField);

                const request = JSON.stringify(search.lastSearch);
                return this.rest.post(search.urls.get, request, true);
            }));
}

public _countTotalSearch(search: Search): Observable < number > {
    const timeOptions: DateCriteria = this._getTimeStartEnd(search);

    return this.store.pipe(
        select(getFilterById(search.filterId)),
        first(),
        concatMap((filter: Filter) => {
            const indicators = [{
                    'criterias': this.filterService.getActiveCriterias(filter)
                }
            ];
            const request = new TransactionRequest(
                    0, 0, timeOptions.begin, timeOptions.end,
                    indicators, null, search.searchField.trim());

            return this.rest.post(search.urls.count, JSON.stringify(request), true);
        }));
}

我启动了我的spec.ts如下:

    describe('SearchService', () => {
  let searchService: SearchService;
  let store: MockStore;
  let itemsRestService: ItemsRestService;
  let restService: RestService;
  let scheduler: TestScheduler;
  let filterService: FilterService;

  const filterForSelector = TestModelFactory.generateFilter();
  beforeEach(() => {
    TestBed.configureTestingModule({
      imports: [
        TranslateModule.forRoot(),
        HttpClientTestingModule
      ],
      providers: [
        SearchService,
        RestService,
        ItemsRestService,
        ReturnCodeRestService,
        {
          provide: FilterService,
          useValue: {}
        },
        {
          provide: DataMapperService,
          useValue: {}
        },
        provideMockStore({
          selectors: [
            {
              selector: 'getFilterById',
              value: filterForSelector
            }
          ]
        })
      ]
    });

    searchService = TestBed.inject(SearchService);
    itemsRestService = TestBed.inject(ItemsRestService);
    restService = TestBed.inject(RestService);
    filterService = TestBed.inject(FilterService);
    scheduler = new TestScheduler(((actual, expected) => {
      expect(actual).toEqual(expected);
    }));
    store = TestBed.inject(MockStore);
  });
});

我尝试了很多东西,比如订阅,或者弹珠......但我无法让它工作。我想检查结果(observableFromApi)并检查发布请求:

  describe('getSearch', () => {
it('should select filters in store and call api', done => {
  // init vars
  const dateCriteria = new DateCriteria(faker.date.recent().getTime(), faker.date.recent().getTime());
  const resultFromApi = faker.random.word() as any;
  const observableFromApi = of(resultFromApi);
  const search = TestModelFactory.generateSearch();

  // spy
  spyOn(restService, 'post');
  spyOn(searchService, '_getTimeStartEnd');

  // mocks
  filterService.getActiveCriterias = jest.fn(() => faker.random.word() as any);
  searchService._getTimeStartEnd = jest.fn(() => dateCriteria);
  restService.post = jest.fn(() => observableFromApi);

  // call and expect
  expect(searchService._getSearch(search)).toEqual(observableFromApi);
  expect(restService.post).toHaveBeenCalledWith(search.urls.get, '', true);
});
  });

你能帮我吗?

编辑 :

这样它开始工作,但我有一个错误:

  describe('getSearch', () => {
it('should select filters in store and call api', done => {
  // init vars
  const dateCriteria = new DateCriteria(faker.date.recent().getTime(), faker.date.recent().getTime());
  const resultFromApi = faker.random.word() as any;
  const observableFromApi = of(resultFromApi);
  const search = TestModelFactory.generateSearch();

  // spy
  spyOn(restService, 'post');
  spyOn(searchService, '_getTimeStartEnd');

  // mocks
  filterService.getActiveCriterias = jest.fn(() => faker.random.word() as any);
  searchService._getTimeStartEnd = jest.fn(() => dateCriteria);
  // const expectedObservable = cold('a|', {a : observableFromApi});
  // restService.post = jest.fn(() => expectedObservable);

  restService.post = jest.fn(() => observableFromApi);

  searchService._getSearch(search).subscribe(res => {
    done();
    expect(res).toBe(observableFromApi);
    expect(restService.post).toHaveBeenCalledWith(search.urls.get, '', true);
  });
});
  });

这是错误,我认为选择器未正确模拟,未调用 flatMap,我在选择器之前添加了一个点击并被调用。

  console.error
    Error: Uncaught [TypeError: Cannot read property 'ids' of undefined]

编辑 2:

当我尝试模拟我的选择器时出现以下错误:

在此处输入图像描述

这就是我声明选择器的方式,请问这里有什么问题?

export const getFilterById = (id) => createSelector(selectAll, (allItems: Filter[]) => {
  if (allItems) {
    return allItems.find((item: Filter) => {
      return item.id === id;
    });
  } else {
    return null;
  }
});
4

1 回答 1

0

我通过在方法中提取选择器找到了解决方案:

  public _getSearch(search: Search): Observable<any[]> {
    const timeOptions: DateCriteria = this._getTimeStartEnd(search);
    const searchField: string = this._decodeHexIfNecessary(search.searchField.trim());

    const filterObservable: Observable<Filter> = this._getFilterById(search);

    const result = filterObservable.map((filter: Filter) => {
      // Préparation de la requête
      const indicators = [{ 'criterias': this.filterService.getActiveCriterias(filter) }];
      search.lastSearch = new TransactionRequest(
        search.offset, search.pageSize, timeOptions.begin, timeOptions.end,
        indicators, search.sortData, searchField
      );

      const request = JSON.stringify(search.lastSearch);
      return this.rest.post(search.urls.get, request, true);
    });
    return result as Observable<any>;
  }
  
  public _getFilterById(search: Search) {
    return this.store.select(getFilterById(search.filterId));
  }

然后我在我的测试中嘲笑了这个方法:

searchService._getFilterById = jest.fn(() => of(filterForSelector));
于 2020-07-03T09:38:30.687 回答