所以我尝试使用 Jest 模拟嵌套在其他辅助函数中的辅助函数。
我真正要测试的函数的基本结构是这样的
import matrixClient from '@mapbox/mapbox-sdk/services/matrix';
// I want to test this function which uses several other helpers
export const getOrderEstimate = async (start, end) => {
// other non-delivery estimate stuff
const deliveryEstimate = await getDeliveryEstimate(start, end);
return {
...otherStuff
delivery: deliveryEstimate
}
}
const getDeliveryEstimate = async (start, end) => {
try {
return await functionThatWrapsMapBox(start, end);
} catch(error) {
// return error
}
}
const functionThatWrapsMapBox = async (start, end) => {
return matrixClient({ accessToken: MAPBOX_TOKEN })
.getMatrix({
points: [{ coordinates: start }, { coordinates: end }],
profile: `driving-traffic`,
})
.send();
}
在我的测试文件中,我试图做这样的事情,
import * as helpers from './order-estimates';
describe('order estimates', () => {
test('delivery estimates should never be null', () => {
const mockMapBox = jest.spyOn(helpers, 'functionThatWrapsMapBox');
mockMapBox.mockReturnValue(() => ...mockedReturn))
// this function always uses the real implementation of functionThatWrapsMapBox
const orderEstimates = helpers.getOrderEstimate(startAddress, endAddress);
expect(orderEstimates.delivery).not.toBeNull();
});
});
我已经尝试了几种使用 jest.mock
的手动模拟技术,我只能让模拟实现触发如果我直接在我的测试文件中调用它,这并不是我真正想要的.我认为 jest.spyOn
方法更合适,但还没有运气。
答案 0 :(得分:0)
我提出的解决方案确实反映了文档 found here。本质上,我将地图框客户端拉到它自己的模块中,该模块与此帮助模块相邻。然后我在 __mocks__
目录中创建了一个模拟实现。然后在我的测试中,它就像在文件顶部放置 jest.mock('./mapbox');
一样简单,并且使用了模拟实现。我现在也可以访问更细粒度的控件。
首先,我将 mapbox 客户端提取到它自己的文件中。
import functionThatWrapsMapBox from './mapbox';
// I want to test this function which uses several other helpers
export const getOrderEstimate = async (start, end) => {
// other non-delivery estimate stuff
const deliveryEstimate = await getDeliveryEstimate(start, end);
return {
...otherStuff
delivery: deliveryEstimate
}
}
const getDeliveryEstimate = async (start, end) => {
try {
return await functionThatWrapsMapBox(start, end);
} catch(error) {
// return error
}
}
所以,mapbox.js
import matrixClient from '@mapbox/mapbox-sdk/services/matrix';
const functionThatWrapsMapBox = async (start, end) => {
return matrixClient({ accessToken: MAPBOX_TOKEN })
.getMatrix({
points: [{ coordinates: start }, { coordinates: end }],
profile: `driving-traffic`,
})
.send();
}
default export functionThatWrapsMapBox;
并在__mocks__/mapbox.js
中:
const functionThatWrapsMapBox = async (origin, destination) => {
return new Promise((resolve, reject) => {
process.nextTick(() => {
if (origin && destination) {
resolve({
body: {
durations: [
[0.0, 135.4],
[131.5, 0.0],
],
},
});
} else {
reject(new Error('Please provide and origin and a destination'));
}
});
});
};
export default functionThatWrapsMapBox;
最后在我的测试中:
import { getOrderEstimate } from './order-estimates';
jest.mock('./mapbox');
describe('order estimates', () => {
test('delivery estimates should never be null', () => {
// this function uses the mock implementation of functionThatWrapsMapBox
const orderEstimates = getOrderEstimate(startAddress, endAddress);
expect(orderEstimates.delivery).not.toBeNull();
});
});
向@jonrsharpe 致以崇高的敬意,感谢他们说明了正确的做法!