所以我试图测试我的实现的积极和消极方面。如果我这样做:

jest.mock('./apiClient', () => ({
  get: jest.fn((url: string) => Promise.resolve({ data: mockData }))
}));

jest.mock('./apiClient', () => ({
  get: jest.fn().mockImplementation((url: string) => {
    console.log('error result');
    return Promise.reject(mockError);
  })
}));

那么唯一通过的测试将是最后一个声明的测试。在上述情况下,将通过 reject 情况,并忽略第一个模拟。

这是我的整个测试:
// @ts-ignore
import ApiClient from './apiClient';
import ApiService from './apiService';

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

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

jest.mock('./apiClient', () => ({
  get: jest.fn((url: string) => Promise.resolve({ data: mockData }))
}));

jest.mock('./apiClient', () => ({
  get: jest.fn().mockImplementation((url: string) => {
    console.log('error result');
    return Promise.reject(mockError);
  })
}));

describe('apiService', () => {
  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();
    });
  });

  it('should handle error', done => {
    console.error = jest.fn();
    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();
    });
  });
});

就像现在一样,测试通过的是 should handle error 这是第二个,但是如果我从
jest.mock('./apiClient', () => ({
  get: jest.fn((url: string) => Promise.resolve({ data: mockData }))
}));

jest.mock('./apiClient', () => ({
  get: jest.fn().mockImplementation((url: string) => {
    console.log('error result');
    return Promise.reject(mockError);
  })
}));


jest.mock('./apiClient', () => ({
  get: jest.fn().mockImplementation((url: string) => {
    console.log('error result');
    return Promise.reject(mockError);
  })
}));

jest.mock('./apiClient', () => ({
  get: jest.fn((url: string) => Promise.resolve({ data: mockData }))
}));

那么测试通过将是 should call callbacks consequently ,那么我可以做些什么来模拟拒绝和解决而不干扰另一个?

最佳答案

我在寻找一个好的做法时遇到了这个问题,因为我遇到了同样的问题,但我找到了一个解决方法来使它工作。虽然我想你已经解决了这个问题,但我会在这里为 future 的读者留下我的临时解决方案。
基本上,我在我想拒绝 promise 的测试中重写了该方法的模拟实现。
所以我会在 describe 声明之前去掉 reject 实现,并通过这种方式将它添加到 'should handle error' 测试中:

ApiClient.get: jest.fn().mockImplementation((url: string) => {
    console.log('error result');
    return Promise.reject(mockError);
})
您的最终测试将如下所示:
// @ts-ignore
import ApiClient from './apiClient';
import ApiService from './apiService';

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

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

jest.mock('./apiClient', () => ({
  get: jest.fn((url: string) => Promise.resolve({ data: mockData }))
}));

describe('apiService', () => {
  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();
    });
  });

  it('should handle error', done => {
    ApiClient.get: jest.fn().mockImplementation((url: string) => {
        console.log('error result');
        return Promise.reject(mockError);
    });
    console.error = jest.fn();
    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();
    });
  });
});
我认为这不是最好的方法,但它一点也不差,它应该适用于这个例子。
我会继续寻找更聪明的解决方案。

关于javascript - 笑话 : How to mock a promise on the same file for resolve and reject options?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/57704755/

10-13 02:09