Không thể kiểm tra phương thức bài với Jest do lỗi không thể đọc mockImcellenceation của không xác định


9

Tôi có một dịch vụ api nơi tôi có các phương thức khác nhau để thực hiện các cuộc gọi đến API. Tôi đã kiểm tra thành công tất cả các yêu cầu GET nhưng tôi gặp sự cố khi kiểm tra các yêu cầu POST.

Đây là phương pháp:

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
    );
  };
};

Đây là cách tôi đang thử nghiệm mọi thứ liên quan đến 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');
    });
  });
})

Tôi nghĩ rằng chỉ bằng cách thay đổi tất cả các trường hợp ApiClient.getđể ApiClient.postnó sẽ làm việc để kiểm tra các yêu cầu POST. Nhưng khi tôi cố gắng làm điều đó thì nói rằng can not read mockImplementation of undefined. Tôi đã thử thay đổi các phương thức trong các thử nghiệm để sử dụng postparam để ghi đè lên param method = 'get'nhưng tôi không thành công, tôi gặp lỗi này

LoạiError: apiClient_1.default.post không phải là một chức năng

Có suy nghĩ gì không?


Một trong những lý do sẽ là ApiClientkhông có phương pháp post.
Tomas

Xin chào, @Tomas nhìn vào dòng này -> return ApiClient.post(url, data, config) .then(res => callback(normalizeCallback(res.data))).catch(error => someHandler(error));và nó hoạt động đúng khi tôi cố gắng thực hiện một yêu cầu bài viết. Tôi có nghĩa là tôi có 17 bài viết yêu cầu làm việc như họ phải. Vậy tại sao trong các bài kiểm tra không hoạt động?
Phản ứng

@Reacting Vui lòng chia sẻ ví dụ kiểm tra đơn vị "bài"
Oron Ben-David

@ OronBen-David Tôi đã đề cập trong câu hỏi rằng tôi đã thử chính xác giống như trong getbài kiểm tra nhưng tôi đã thay đổi tất cả các trường hợp getvà đặt postthay thế.
Phản ứng

Tôi hiểu, nhưng sẽ rõ ràng hơn khi đề cập đến mã không hoạt động
Oron Ben-David

Câu trả lời:


5

Tôi đã điều tra vấn đề của bạn. Trước hết, tôi muốn nói rằng mã của bạn có một số vấn đề như gọi lại mà bạn không xác định, không xác định rõ ràng, ApiClientv.v.

Vì vậy, tôi đã tạo một ví dụ Thay thế để tái tạo vấn đề của bạn, trong đó tôi đã đơn giản hóa mã của bạn một chút nhưng tất cả các yếu tố chính đều ở đó.

Xin vui lòng, hãy xem https://repl.it/@SergeyMell/Some-Jesting

Nó hoạt động thành công cho cả hai getpostphương pháp không có vấn đề. Dưới đây là những điểm chính bạn nên chú ý:

  1. Sử dụng axiosnhư ApiClient. (Không rõ ràng từ câu hỏi của bạn nên tôi cho rằng nó là như vậy)
    const ApiClient = require('axios');
  2. Đặt chế độ giả lập trên axios(Giả sử, bạn cũng làm như vậy)
    jest.mock('axios');
  3. Đặt giả cho cả hai getpostyêu cầu theo cách tương tự (giống với cách của bạn)

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

Vì vậy, xin vui lòng, kiểm tra ví dụ của tôi, kiểm tra sự khác biệt với mã của bạn và cho tôi biết về một số sự giảm giá bổ sung mà bạn có thể cần.


Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.