我有以下模块,我试图在Jest中测试:
// myModule.js
export function otherFn() {
console.log('do something');
}
export function testFn() {
otherFn();
// do other things
}
如上所示,它导出一些命名函数,重要的是testFn
使用otherFn
。
在Jest中,当我为testFn
编写单元测试时,我想模拟otherFn
函数,因为我不希望otherFn
中的错误影响我的testFn
单元测试。我的问题是我不确定最好的方法是什么:
// myModule.test.js
jest.unmock('myModule');
import { testFn, otherFn } from 'myModule';
describe('test category', () => {
it('tests something about testFn', () => {
// I want to mock "otherFn" here but can't reassign
// a.k.a. can't do otherFn = jest.fn()
});
});
任何帮助/洞察力是赞赏。
8条答案
按热度按时间doinxwow1#
在
jest.mock()
内部使用jest.requireActual()
jest.requireActual(moduleName)
返回实际的模块而不是模拟模块,从而绕过对模块是否应接收模拟实现的所有检查。
示例
我更喜欢这种简洁的用法,你需要在返回的对象中传播:
Jest的Manual Mocks文档中也引用了此方法(靠近 * Examples * 的结尾):
为了确保手动mock和它的真实实现保持同步,在导出它之前,要求真实模块在手动mock中使用
jest.requireActual(moduleName)
并使用mock函数对其进行修改可能是有用的。wz3gfoph2#
看来我来晚了,但这是可能的.
testFn
只需要使用模块 * 调用otherFn
*。如果
testFn
使用该模块调用otherFn
,则可以模拟otherFn
的模块导出,testFn
将调用模拟。下面是一个工作示例:
myModule.js
myModule.test.js
sauutmhj3#
这对我不起作用,我这样做了:
wvt8vs2t4#
我知道这个问题很久以前就被问到了,但我只是遇到了这种情况,最终找到了一个可行的解决方案。所以我想在这里分享一下。
对于模块:
您可以更改为以下内容:
将它们作为常量而不是函数导出。我相信这个问题与JavaScript中的提升有关,使用
const
可以防止这种行为。然后在你的测试中,你可以有如下内容:
模拟现在应该可以正常工作了。
cnwbcb6i5#
编译后的代码将不允许babel检索
otherFn()
所引用的绑定。如果你使用一个函数表达式,你应该能够实现mockingotherFn()
。但是正如@kentcdodds在前面的评论中提到的,您可能不想模拟
otherFn()
。相反,只需为otherFn()
编写一个新的规范,并模拟它所进行的任何必要调用。例如,如果
otherFn()
正在发出一个http请求...在这里,您可能希望模拟
http.get
并基于模拟的实现更新Assert。nxowjjhe6#
基于Brian Adams' answer,这就是我如何能够在TypeScript中使用相同的方法。此外,使用jest.doMock()可以只在测试文件的某些特定测试中模拟模块函数,并为每个模块函数提供单独的模拟实现。
src/module.ts
test/module.test.ts
test/helpers.ts
模块的模拟函数被移动到位于单独文件中的辅助函数
mockModulePartially
中,因此可以从不同的测试文件(通常可以位于其他目录中)使用它。它依赖于expect.getState().testPath
来固定到被模拟的模块(modulePath
)的路径(使其相对于包含mockModulePartially
的helpers.ts
)。作为第二个参数传递给mockModulePartially
的mocksCreator
函数应该返回模块的模拟。此函数接收originalModule
,模拟实现可以选择依赖它。bxpogfeg7#
我用我在这里找到的混合答案解决了我的问题:
myModule.js
myModule.test.js
dgjrabp28#
在第一个答案的基础上,你也可以使用babel-plugin-rewire来模拟导入的命名函数。您可以从表面上查看这一节,了解命名函数的重新连接。
对于您的情况,这里的一个直接好处是您不需要更改从您的函数调用其他函数的方式。