【发布时间】:2019-08-06 20:28:50
【问题描述】:
node.js 的新手。我正在编写一个包装底层axios 库的JS API 客户端。在单元测试中,我使用 Jest 模拟 axios。
在我的 API 类的构造函数中,我传入一个 URL,并使用 axios.create 函数创建一个自定义的 axios 实例并将其绑定到客户端属性。
当我使用 jest.mock('axios') 模拟 axios 依赖项时出现问题 - 尝试调用 axios.get 时在测试中引发 TypeError:
TypeError: Cannot read property `get` of undefined
我明白为什么会发生这种情况,但我还没有找到一种方法来模拟 axios 并且不让客户字段未定义。除了通过构造函数注入 axios 之外,有没有办法解决这个问题?
客户端代码和测试如下:
client.js
jest.mock("axios");
const axios = require("axios");
const mockdata = require("./mockdata");
const ApiClient = require("../../../src/clients/apiclient");
const BASE_URL = "https://www.mock.url.com"
const mockAxiosGetWith = mockResponse => {
axios.get.mockResolvedValue(mockResponse);
};
test("should make one get request", async () => {
mockAxiosGetWith(MOCK_RESPONSE)
// the client field in apiclient is undefined
// due to the jest module mocking of axios
const apiclient = new ApiClient.AsyncClient(BASE_URL);
// TypeError: Cannot read property `get` of undefined
return await apiclient.get("something").then(response => {
expect(axios.get).toHaveBeenCalledTimes(1);
});
});
client.test.js
const axios = require("axios");
const getClient = (baseUrl = null) => {
const options = {
baseURL: baseUrl
};
const client = axios.create(options);
return client;
};
module.exports = {
AsyncClient: class ApiClient {
constructor(baseUrl = null) {
this.client = getClient(baseUrl);
}
get(url, conf = {}) {
return this.client
.get(url, conf)
.then(response => Promise.resolve(response))
.catch(error => Promise.reject(error));
}
}
};
【问题讨论】:
-
你不要模拟 axios 的实现。应该有
jest.mock("axios", () => ({ get: jest.fn }))。我不能说这是否是这里唯一的问题。 -
@estuthanks 回复。 jest 允许使用 jest.fn 自动模拟每个导出的函数的模块模拟 - 这不是这里的问题。
-
但是
axios只导出一个拥有create函数的对象。这与直接导出create的模块不同。所以@estusis 对他关于如何模拟axios的建议是正确的。即使是真正的嘲笑也应该看起来不同。我会提供答案。
标签: javascript node.js unit-testing jestjs axios