Unit testing 不要嘲笑别人
请帮我理解笑话 我在文件中放入了一些伪函数:Unit testing 不要嘲笑别人,unit-testing,jestjs,Unit Testing,Jestjs,请帮我理解笑话 我在文件中放入了一些伪函数: //actions.js 导出函数f1(){ 返回1 } 导出函数调用_f1(){ f1() } 然后在我的测试文件中,我试图了解如何检查一个函数是否调用另一个函数: import*作为“/actions.js”中的操作 描述(“模拟”),()=>{ actions.f1=jest.fn(); actions.calls_f1(); expect(actions.f1).toBeCalled(); }); 但是测试失败了,因为没有调用模拟函数。我
//actions.js
导出函数f1(){
返回1
}
导出函数调用_f1(){
f1()
}
然后在我的测试文件中,我试图了解如何检查一个函数是否调用另一个函数:
import*作为“/actions.js”中的操作
描述(“模拟”),()=>{
actions.f1=jest.fn();
actions.calls_f1();
expect(actions.f1).toBeCalled();
});
但是测试失败了,因为没有调用模拟函数。我也尝试过交换测试的第2行和第3行,但没有效果
我的jest配置很好,实际上我已经做了一系列其他的测试(在同一个文件中)可以正常工作
我错过了什么
注意:此操作的实际实现(我在这里大大简化)涉及一个
操作
文件,该文件包含一个公共导出函数fetchStations()
,该函数调用私有(或者,不是导出的)导出函数\u downloadStations()
。我试图测试是否调用了\u downloadStations()
我使用import*作为操作
只是为了方便,所以我可以写这一行,然后使用文件在actions.whatever()
下导出的任何函数(而不必在我决定使用函数时向import语句添加函数)。如果import*as actions
有一些我没有注意到的效果(如下面brian所暗示的),那么我当然不必使用它,当然可以使用import{thisAction,thatAction}从“/actions”
导入。这一行:
import*作为“/actions.js”中的操作
将模块从actions.js导出绑定到actions
…因此,将actions.f1
设置为模拟函数将取代f1
的模块导出
…但这不会影响调用_f1
,因为它直接调用f1
如果calls\u f1
更改为调用f1
的模块导出,则它将调用模拟函数
有两种方法可以实现这一点
一种方法是将f1
移动到它自己的模块中
另一种方法是注意ES6模块(ES6模块的主要设计目标),以便模块可以导入自己的导出:
actions.js
import*作为来自“/actions”的操作;//{
actions.f1=jest.fn();
actions.calls_f1();
expect(actions.f1).toBeCalled();//成功!
})
})
更新
OP更新了问题,以指示所述函数未从模块导出
在这种情况下,它只是模块的内部实现细节,不能直接监视
测试它需要测试它所造成的影响,而不是直接监视它是否被调用。谢谢Brian。我确实(当然)得到了这个精确的代码。在我的操作
文件中不包含循环导入的情况下,如何执行此操作?似乎额外的导入只是为了让测试正常工作。也许正如你所说,这是“把f1放在它自己的模块中”,但我不太清楚这意味着什么。只需要有一个间接层次……调用f1
作为对象的属性。这使您可以使用模拟替换对象的属性。如果直接调用f1
,则无法重写该命令。将一个模块导入到其自身中会起作用,将两个函数都放在包装对象中会起作用,将f1
移动到另一个模块中会起作用,以对您最有意义的模块为准@JonathanTuzman“将f1放入它自己的模块”仅仅意味着创建另一个包含f1
的文件(例如f1.js
),然后将其导入到actions.js
中,以便调用\u f1
将其作为模块的属性进行调用,该属性在…中定义,为您提供了在测试期间用不同的内容替换它所需的间接性@JonathanTuzmanah,如果未导出\u downloadStations
,则无法将其包装在spy中,以测试它是否已被调用,因为它只是模块的内部实现细节,在模块外部不可见。在这种情况下,您只能测试调用\u downloadStations
所造成的影响…我在下面的回答中添加了一个更新以反映该信息。我已对其进行编辑,使其具有导出功能\u downloadStations
。我可以进行此更改以使测试成为可能(或者使用rewre或其他方法使其成为可能,而无需公开方法)。仍然没有在源文件中执行任何循环导入。