JavaScript中类似Python的函数模拟
使用JavaScript中类似Python的函数模拟,javascript,python,testing,mocking,jestjs,Javascript,Python,Testing,Mocking,Jestjs,使用Python很容易模拟测试函数中使用的函数 # my_module.py def function_a(): return 'a' def function_b(): return function_a() + 'b' # tests/test_my_module.py from unittest import TestCase from unittest.mock import patch from my_module import function_b c
Python
很容易模拟测试函数中使用的函数
# my_module.py
def function_a():
return 'a'
def function_b():
return function_a() + 'b'
# tests/test_my_module.py
from unittest import TestCase
from unittest.mock import patch
from my_module import function_b
class MyModuleTestCase(TestCase):
@patch('my_module.function_a')
def test_function_b(self, mock_function_a):
mock_function_a.return_value = 'c'
self.assertEqual(function_b(), 'cb')
在JavaScript
中,例如使用jest
,是否可以这样做
# myModule.js
function myFunctionA() {
return 'a';
}
export function myFunctionB() {
return myFunctionA() + 'b';
}
# __test__/test.myModule.js
import { myFunctionB } from '../myModule';
describe('myModule tests', () => {
test('myFunctionB works', () => {
// Mock `myFunctionA` return value here somehow.
expect(myFunctionB()).toBe('cb')
});
});
我已经读过了,但仍然不知道如何做,因为有太多(黑客)建议(其中一些建议已经有2年了)。
Jest
可以使用模拟整个模块,也可以将模拟单个模块导出与以下功能结合使用
这使得模拟从库导入的函数变得很容易:
/--lib.js----
导出函数myfunction(){
返回“a”;
}
//----myModule.js----
从“./lib”导入{myfunction};
导出函数myFunctionB(){
返回myfunction()+'b';//调用lib.myfunction()
}
//----myModule.test.js----
从“/myModule”导入{myFunctionB};
将*作为库从“/lib”导入;
描述('myModule测试',()=>{
测试('myFunctionB工作',()=>{
const mock=jest.spyOn(lib,'myfunction');//在lib.myfuncto()上创建一个间谍
mock.mockImplementation(()=>'c');//替换该实现
expect(myFunctionB()).toBe('cb');
mock.mockRestore();//删除间谍和模拟实现
});
});
在问题
myModule
的代码示例中,包含两个函数,一个函数直接调用另一个函数
由于模拟可以在整个模块或模块导出上工作,因此从myFunctionB()
中模拟对myfunction()的直接调用对于编写代码的方式来说是非常困难的
我发现解决这种情况的最简单方法是将模块导入自身,并在调用函数时使用模块。这样,调用的是模块导出,并且可以在测试中对其进行模拟:
/----myModule.js----
从“/myModule”导入*作为myModule;
导出函数myfunction(){
返回“a”;
}
导出函数myFunctionB(){
返回myModule.myFunctionA()+'b';//调用myModule.myFunctionA()
}
//----myModule.test.js----
从“/myModule”导入*作为myModule;
描述('myModule测试',()=>{
测试('myFunctionB工作',()=>{
const mock=jest.spyOn(myModule,'myFunctionA');//在myModule.myFunctionA()上创建一个间谍
mock.mockImplementation(()=>'c');//替换该实现
expect(myModule.myFunctionB()).toBe('cb');
mock.mockRestore();//删除间谍和模拟实现
});
});
谢谢!我已经寻找这个答案很久了@伟:太棒了,很高兴听到这对你有帮助!不幸的是,这不如python的mock.patch强大:|有了它,就可以模拟任何模块可以访问的任何属性(除了内置对象的属性,python不擅长这一点,但这些通常不是问题,因为您通常可以模拟整个内置对象)。谢谢你的回答,很有帮助!