Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/unit-testing/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Unit testing 不要嘲笑别人_Unit Testing_Jestjs - Fatal编程技术网

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或其他方法使其成为可能,而无需公开方法)。仍然没有在源文件中执行任何循环导入。