javascript - 模拟多层深度的 API 调用
问题描述
所以我试图模拟一个嵌套在其他辅助函数中的辅助函数,使用 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
解决方案
我想出的解决方案确实反映了此处找到的文档。本质上,我将地图框客户端拉到它自己的模块中,与这个助手模块相邻。__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 来说明正确的方法!
推荐阅读
- docker - 如何附加到 dockerfile 或 docker run 中的路径
- delphi - 返回结果集后发生 SQL 错误时如何强制 TADOConnection 抛出异常
- php - 电子窗口在加载时为空白
- c# - 缺少 App1.Pages.SetPageDetail 的默认构造函数(位置 12:18)
- java - api调用后进行数据库插入时并发用户数据库超时问题
- javascript - 如何使用谷歌图表在同一图表上绘制散点图和折线图
- javascript - 让 chart.js 填充垂直空间
- macos - How to make C library installable with angle brackets as
on Mac - git - 如何从 git 中获取所有未在 Visual Studio 中添加或提交的丢弃文件
- ansible - 无法在 Ansible 中使用 deb 模块卸载包