Javascript commonJS要求默认导出函数返回默认函数
我在JavaScript中遇到了一些让我感到困惑的东西,我希望能找到一个解释 我正在编写一个Jest测试,它需要模拟我编写的自定义模块,我正在测试的助手函数依赖于该模块。此外,我需要重写自定义模块中的方法,以更改其正常输出,从而引发异常,而不是测试不满意的路径 下面是我的模拟模块的外观:Javascript commonJS要求默认导出函数返回默认函数,javascript,ecmascript-6,jestjs,Javascript,Ecmascript 6,Jestjs,我在JavaScript中遇到了一些让我感到困惑的东西,我希望能找到一个解释 我正在编写一个Jest测试,它需要模拟我编写的自定义模块,我正在测试的助手函数依赖于该模块。此外,我需要重写自定义模块中的方法,以更改其正常输出,从而引发异常,而不是测试不满意的路径 下面是我的模拟模块的外观: // ../helperFunctions/__mocks__/CreateRequestObject.js // This is the mock function for getFileList() ex
// ../helperFunctions/__mocks__/CreateRequestObject.js
// This is the mock function for getFileList()
export default function () {
return {
post: () => ({
data: [
"folder1/file1.doc",
"folder1/folder2/file2.doc",
"folder1/folder3/file3.doc"
],
}),
};
}
从,它建议首先调用jest.mock('path/to/module/tobe/mocked')然后,需要原始文件constmymodule=require('path/to/module/tobe/mocked')代码>。然后,调用myModule.methodName.mockImplementation(()=>{…})代码>在我的测试中更改实现
但是,当我尝试在require
之后调用该方法时,会收到一个错误,指出该方法不存在。执行console.log()
显示[默认:函数]
出于好奇,我调用了console.log(myModule.default())
,看到{post:[Function post]}
使用VSCode转到模拟模块文件,并将鼠标悬停在关键字default
上,我看到以下覆盖:
function default(): {
post: () => ({ data: string[] });
}
我的问题是,当我需要从使用export default
关键字的文件中导出时,为什么会将default作为函数返回?导出默认值是如何工作的
此外,调用mockImplementation不起作用,我不明白为什么。问题
我不确定这是否是解决这个问题的方法。我欢迎其他更有知识的人加入使用Jest框架设置测试的行列
最初,我认为我应该这样组织测试:
在/helperFunctions/\uuuuuumocks\uuuuuu/createRequestObject.js中创建自定义模块“createRequestObject”的模拟版本
在HelperFunctions.test.js中,调用jest.mock('../HelperFunctions/CreateRequestObject')
在顶部的“../helperFunctions/createRequestObject”中添加import createRequestObject
,然后在我的特定测试中,调用createRequestObject.mockImplementation(()=>{throw new RequestException(…)}
执行此操作时,我遇到错误消息“createRequestObject”不是函数
这是因为在导入函数时,函数已经执行并返回了一个对象
下一个问题是,该对象是一个固定对象,其中包含一个post方法,该方法返回一个包含一些数据的对象。所有这些都不能修改。请将其视为一个静态不可变图像
我想要的是能够在测试之间动态更改模块的实现,以确保我的助手函数getFileList()
,它将在幕后调用createRequestObject()
,以a)返回模拟成功API调用的数据集,或b)在API调用失败时抛出错误
解决方案
在/helperFunctions/\uuuuu mocks\uuuu/CreateRequestObject.js
中,我现在有以下代码:
导出默认jest.fn()代码>
jest.fn()
将返回一个对象,该对象可以访问我需要动态更改实现的所有模拟方法
在我的HelperFunctions.test.js
中,我现在可以像上面那样导入createRequestObject,但是现在可以多次调用createRequestObject.mockImplementationOnce(()=>{…})
来设置我的测试,这是我的初衷
我希望这些信息能帮助其他同样面临类似问题的人。请发布模拟的myModule.js
的确切内容。它真的有出口吗?实际模块是如何实现的?它是如何加载的?嗨@Bergi,我已经添加了一些额外的细节。希望这能让事情变得更清楚一点。我正试图替换您在那里看到的post方法的实现,但我没有成功。我遵循Jests文档中的示例,但尚未成功。createRequestObject。默认值是一个函数,它将使用post
方法返回对象。它本身没有.post
属性。因此,是的,createRequestObject.default.post.mockImplementation
不存在,应该引发异常。(另外,该行的其余部分似乎会导致语法错误,可能缺少括号?)因此,如果我想在helperFunctions.test.js中调用getFileList()时重写该post方法,我如何使用Jest实现这一点?我试图调用`createRequestObject.default().post.mockImplementationOnce(()=>{…}),但它仍然告诉我mockImplementationOnce()不是一个函数。您需要做的是编写helperFunctions/\uuuumocks\uuuu/createRequestObject.js
文件(与原始API相同),然后调用jest.mock('../helperFunctions/CreateRequestObject')
。
// ../helperFunctions/RequestActions.js
import createRequestObject from './CreateRequestObject';
import RequestException from '../exceptions/RequestExceptions';
async function getFileList(path) {
/*
Returns:
* [] if there are no files or folders found in the path
* An array of file names as strings if one or more files are found
Throws:
* RequestException when request fails
*/
try {
const api = createRequestObject();
const response = await api.post('/endpoint', { path });
const dataSet = response.data;
return dataSet;
} catch (e) {
throw new RequestException(e);
}
}
export default getFileList;
// ../helperFunctions/helperFunctions.test.js
import createRequestObject from '../helperFunctions/CreateRequestObject';
import getFileList from '../helperFunctions/RequestActions';
import RequestException from '../exceptions/RequestExceptions';
test(`getFileList() API call failure should throw RequestException error`,
async () => {
// Arrange
const path = 'folder1/folder2/folder3';
const createRequestObject = require('../helperFunctions/CreateRequestObject');
createRequestObject.default.post.mockImplementation() => ({
post: () => {
throw new RequestExeception({
message: 'No Network',
config: {
baseURL: 'https://www.example.com',
url: '/endpoint',
})
}
}));
// Act
const data = await getFileList(path);
// Assert
expect(data).toThrow();
});
function default(): {
post: () => ({ data: string[] });
}