所以我试图测试我的实现的积极和消极方面。如果我这样做:
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
情况将通过,第一个 mock 将被忽略。
这是我的整个测试:
// @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 }))
}));
然后测试通过将是应该调用回调
,那么我可以做些什么来模拟 reject 和 resolve 而不会相互干扰?
最佳答案
我在寻找一个好的做法时遇到了这个问题,因为我遇到了同样的问题,但我找到了解决方法来解决这个问题。尽管我想您已经解决了这个问题,但我还是将我的临时解决方案留在这里供 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 - Jest : How to mock a promise on the same file for resolve and reject options?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57704755/