如何分别测试服务的每种方法?

问题描述 投票:0回答:1

我有一个调用API的服务。我已经创建了一个测试该服务的一般范式的测试,但是我需要在该服务中逐个方法进行测试。

这是服务:

import ApiClient from './apiClient';
import ApiNormalizer from './apiNormalizer';
import Article from '../models/Article.model';
import { ContentWithFacet } from '../types/contentWithFacets';
import EventModel from '../models/Event.model';

export interface ResponseData {
  [key: string]: any;
}

export default class ApiService {
  static makeApiCall = <T>(
    url: string,
    normalizeCallback: <T>(d: ResponseData) => T | any,
    callback: (d: T) => any
  ): Promise<void> =>
    ApiClient.get(url)
      .then(res => {
        callback(normalizeCallback(res.data));
      })
      .catch(error => {
        console.error(`ApiClient ${url}`, error);
      });

  static getHomeArticles = (
    callback: (a: ResponseData) => void,
    limit: string,
    sort: string
  ): Promise<void> =>
    ApiService.makeApiCall<Article[]>(
      `content?type=article&limit=${limit}&sort=${sort}`,
      ApiNormalizer.normalizeArticles,
      callback
    );

  static getEvents = (
    callback: (a: EventModel[]) => void,
    pageCount?: number,
    limit?: number,
    sort?: string
  ): Promise<void> =>
    ApiService.makeApiCall(
      `content?type=event&page=${pageCount}&limit=${limit}&sort=${sort}`,
      ApiNormalizer.normalizeEvents,
      callback
    );
}

这是我的测试:

import ApiClient from './apiClient';
import ApiService from './apiService';

const mockData = {};
const mockError = { message: 'Smth Bad Happened' };

jest.mock('./apiClient', () => {
  return {
    get: jest.fn()
  };
});

const firstCallback = jest.fn((data: any) => data);
const secondCallback = jest.fn((data: any) => data);

describe('apiService', () => {
  beforeAll(() => {
    // @ts-ignore
    ApiClient.get.mockImplementation((url: string) => {
      return Promise.resolve({ data: mockData });
    });
  });

  it('should call api client method', () => {
    ApiService.makeApiCall('testUrl', data => data, res => res);
    expect(ApiClient.get).toBeCalledTimes(1);
    expect(ApiClient.get).toBeCalledWith('testUrl');
  });

  it('should call callbacks consequently', done => {
    ApiService.makeApiCall('testUrl', firstCallback, secondCallback).then(
      () => {
        expect(firstCallback).toBeCalledTimes(1);
        expect(firstCallback).toBeCalledWith(mockData);
        expect(secondCallback).toBeCalledTimes(1);
        expect(secondCallback).toBeCalledWith(firstCallback(mockData));
        done();
      }
    );
  });
});

describe('api service error flow', () => {
  beforeAll(() => {
    // @ts-ignore
    ApiClient.get.mockImplementation((url: string) => {
      console.log('error result');
      return Promise.reject(mockError);
    });
  });

  it('should handle error', done => {
    console.error = jest.fn();

    const firstCallback = jest.fn((data: any) => {
      return data;
    });
    const secondCallback = jest.fn((data: any) => {
      return data;
    });
    ApiService.makeApiCall('test url', firstCallback, secondCallback).then(
      () => {
        expect(firstCallback).toBeCalledTimes(0);
        expect(secondCallback).toBeCalledTimes(0);
        expect(console.error).toBeCalledTimes(1);
        expect(console.error).toBeCalledWith('ApiClient test url', mockError);
        done();
      }
    );
  });
});

如您在上面看到的,我仅测试ApiService.makeApiCall方法,但是我想测试getHomeArticlesgetEvents方法。

关于如何模拟那些方法以完成测试的任何想法?

javascript reactjs typescript ecmascript-6 jest
1个回答
0
投票

您可以通过模拟ApiService.makeApiCall来编写getHomeArticles的新测试用例,因为在getHomeArticles内部将调用此方法。我们应该始终将孤立的小块的测试用例编写为独立的用例。内部调用应被嘲笑,因为它已经作为独立调用进行了测试。在这种情况下,您只有一个makeApiCall可以测试它是否已调用并使用正确的参数集进行了调用]

it('should call getHomeArticles', done => {
   // as this method call makeApiCall, you mock it.
   ApiClient.makeApiCall.mockImplementation(
      (url: string,
      normalizeCallback: <T>(d: ResponseData) => T | any,
      callback: (d: T) => any) => {
          return Promise.resolve({ data: {});
   });

    ApiClient.getHomeArticles(firstCallback, "limit", "sort").then(
    () => {
      expect(ApiClient.makeApiCall).toBeCalledTimes(1); // called
      expect(ApiClient.makeApiCall).toBeCalledWith('content?type=article&limit=limit&sort=sort', ApiNormalizer.normalizeArticles, firstCallback ); // check its called with right argument


    );
});

注意:您可以根据需要更改代码。这是您可以在getHomeArticles方法

中测试的演示
© www.soinside.com 2019 - 2024. All rights reserved.