由于错误而无法使用Jest测试发布方法无法读取未定义的嘲笑


9

我有一个api服务,在这里我有不同的方法来调用API。我已经成功测试了所有GET请求,但是在测试POST请求时遇到了麻烦。

这是方法:

export default class ApiService {
  static makeApiCall = <T>(
    url: string,
    oneCb: <T>(d: Data) => T,
    secondCb: (d: T) => void,
    errorCb?: (a: ErrorModel) => void,
    method = 'get',
    data = {},
  ): Promise<void> => {
    const config: AxiosRequestConfig = {};
    if (method === 'post') {
      config.headers = header;
      return ApiClient.post(url, data, config)
        .then(res => callback(normalizeCallback(res.data))).catch(error => someHandler(error));            
    } else {
      return ApiClient.get(url)
        .then(res => callback(normalizeCallback(res.data))).catch(error => someHandler(error));
    }
  };

  // ONLY ONE POST METHOD TO MAKE IT MORE CLEAR
  static someArchiveMethod = (
    callback: (a: SuccessModel) => void,
    errorCallback: (error: ErrorModel) => void,
    cardId: string
  ): Promise<void> => {
    return ApiService.makeApiCall<SuccessfulResponse>(
      'appreciationCard/archive',
      Normalizer.successfulResponse,
      callback,
      errorCallback,
      'post',
      { cardId }
    );
  };

  // HERE BELOW THE GET METHODS
  static getPeople = (cb: (a: PeopleModel[]) => void, page?: number, limit?: number): Promise<void> => {
    const queryDetails = { page, limit };
    return ApiService.makeApiCall<PeopleModel[]>(
      `people?${toQueryString(queryDetails)}`,
      Normalizer.normalizePeople,
      callback
    );
  };
};

这就是我测试与GET相关的所有内容的方式:

describe('apiService', () => {
  beforeAll(() => {
    expect(ApiClient.defaults.headers.common.Authorization).toBe('Bearer test token');
    // @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,
      err => err,
      'get'
    );

    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) => data);
    const secondCallback = jest.fn((data: any) => data);

    ApiService.makeApiCall('testUrl', firstCallback, secondCallback).then(() => {
      expect(firstCallback).toBeCalledTimes(0);
      expect(secondCallback).toBeCalledTimes(0);
      expect(console.error).toBeCalledTimes(1);
      expect(console.error).toBeCalledWith('ApiClient testUrl', mockError);
      done();
    });
  });
});

describe('apiService methods', () => {
  beforeAll(() => {
    ApiClient.get.mockImplementation((url: string) => {
      expect(ApiClient.defaults.headers.common.Authorization).toBe('Bearer test token');

      return Promise.resolve({ data: mockData });
    });
  });

  it('getPeople method call with one param', () => {
    ApiService.getPeople(jest.fn(), 1, 1).then(() => {
      expect(ApiClient.get).toBeCalledWith('people?page=1&limit=1');
    });
  });
})

我认为,只有通过改变所有的实例ApiClient.get,以ApiClient.post它的工作来测试POST请求。但是,当我尝试这样做时,它就是这么说的can not read mockImplementation of undefined。我尝试更改测试中的方法以使用post参数以覆盖参数,method = 'get'但是我没有成功,但出现此错误

TypeError:apiClient_1.default.post不是函数

有什么想法吗?


原因之一ApiClient是没有方法post
托马斯

嗨,@Tomas看这行-> return ApiClient.post(url, data, config) .then(res => callback(normalizeCallback(res.data))).catch(error => someHandler(error));并且当我尝试执行发布请求时,它可以正常工作。我的意思是,我喜欢17个帖子请求,它们必须按要求工作。那么为什么在测试中不起作用呢?
反应

@Reacting请分享“发布”单元测试示例
Oron Ben-David

@ OronBen-David我在问题中提到我尝试与get测试完全相同,但是我更改了所有实例get并设置了它post
反应

我了解,但是提到不起作用的代码会更加清楚
Oron Ben-David

Answers:


5

我已经调查了您的问题。首先,我想告诉您的代码有两个问题,例如调用未定义的回调,不清楚的定义ApiClient等。

因此,我创建了一个Repl示例来重现您的问题,其中我简化了代码,但所有主要元素都在那儿。

请看看 https://repl.it/@SergeyMell/Some-Jesting

它对方法getpost方法都成功,没有问题。这里是您应注意的要点:

  1. 使用axiosApiClient。(您的问题不清楚,因此我认为是这样)
    const ApiClient = require('axios');
  2. 设置开玩笑的模拟axios(假设您执行相同操作)
    jest.mock('axios');
  3. 以相似的方式将模拟放到请求get和两者post(与您的方式相同)

    ApiClient.get.mockImplementation((url) => {
      return Promise.resolve({ data: mockData });
    });
    
    ApiClient.post.mockImplementation((url) => {
      return Promise.resolve({ data: mockData });
    });

因此,请检查我的示例,检查与您的代码的差异,并让我知道您可能需要的其他一些细节。


By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.