跳到主要内容
版本:25.x.

手动模拟

手动模型用于通过模拟数据停止功能。例如,您可能希望创建一个手动模型,而不是访问像网站或数据库,而不是访问远程资源,允许您使用假数据。这确保了您的测试将快速而不是片状。

嘲笑用户模块

手动模块是通过在a中写入模块来定义的__mocks __ /子目录紧接在模块附近。例如,要模拟一个调用的模块用户楷模目录,创建一个名为user.js把它放进模型/ __mocks__目录。请注意__mocks__文件夹区分大小写,所以命名目录__mocks__将突破一些系统。

当我们在测试中需要该模块时,显式调用jest.mock('./ modulename')必需的

模拟节点模块

如果你正在模拟的模块是一个节点模块(例如:洛奇),嘲笑应该放在__mocks__目录相邻node_modules.(除非您配置了以指向项目根目录以外的文件夹)自动地嘲笑。不需要显式调用jest.mock('module_name')

范围模块(也称为范围包)可以通过在与作用域模块名称匹配的目录结构中创建文件来进行模拟。例如,要模拟一个有作用域的模块@范围/项目名称,创建一个文件__mocks__ / @scope / project-name.js,创造@scope /相应的目录。

警告:如果我们想要模拟节点的核心模块(例如:FS.小路),然后明确地称呼例如jest.mock('path')必需的,因为默认情况下核心节点模块未映射。

例子

├──配置
├──__mocks__
│└──fs.js
├──模特
│├──__mocks__
││└──user.js
│└──user.js
├──node_modules.
└──的观点

当给定模块存在手动模块时,Jest的模块系统将在显式调用时使用该模块jest.mock(“moduleName”)。然而,当汽车被设置为真正的,手动模拟实现将被使用而不是自动创建的模拟,即使jest.mock(“moduleName”)不叫。要选择退出此行为,您需要显式调用jest.unmock('modulename')在测试中,应该使用实际的模块实现。

注意:为了嘲笑,需求jest.mock(“moduleName”)在同一个作用域中要求/导入声明。

这是一个创意的例子,我们有一个模块,它提供给定目录中的所有文件的摘要。在这种情况下,我们使用核心(内置)FS.模块。

/ / FileSummarizer.js
'使用strict' ;
const FS. = 要求 “fs” ;
函数 summarizeFilesInDirectorySync 目录 {
返回 FS. readdirsync. 目录 地图 文件名 = > {
目录
文件名
} ;
}
出口 summarizeFilesInDirectorySync = summarizeFilesInDirectorySync ;

因为我们希望我们的测试能够避免实际碰到磁盘(非常缓慢和脆弱),所以我们为FS.模块,扩展自动模拟。我们的手动模拟将实现自定义版本的FS.我们可以为我们的测试建立的API:

/ / __mocks__ / fs.js
'使用strict' ;
const 小路 = 要求 '小路' ;
const FS. = 笑话 Genmockfrommodule. “fs” ;
//这是一个自定义功能,我们的测试可以在安装期间使用以指定
//“模拟”文件系统上的文件应该看起来像什么时候
//使用`fs` apis。
模仿 = 目的 创建 ;
函数 __setMockFiles newmockfiles. {
模仿 = 目的 创建 ;
为了 const 文件 newmockfiles. {
const 谜语 = 小路 妄想 文件 ;
如果 !! 模仿 [ 谜语 ] {
模仿 [ 谜语 ] = [ ] ;
}
模仿 [ 谜语 ] 小路 basename 文件 ;
}
}
//一个自定义版本的' readdirSync ',从特殊的模拟出来
//通过__setMockFiles设置文件列表
函数 readdirsync. directoryPath {
返回 模仿 [ directoryPath ] || [ ] ;
}
FS. __setMockFiles = __setMockFiles ;
FS. readdirsync. = readdirsync. ;
模块 出口 = FS. ;

现在我们写了我们的测试。请注意,我们需要明确地告诉我们想要嘲笑FS.模块是因为它是一个核心节点模块:

/ / __tests__ / FileSummarizer-test.js
'使用strict' ;
笑话 模拟 “fs” ;
描述 'listfilesindirectorysync' = > {
const mock_file_info. = {
'/path/to/file1.js' 'console.log(“file1内容”);'
'/path/to/file2.txt' “file2内容”
} ;
摘要 = > {
//在每次测试之前设置一些模型的文件信息
要求 “fs” __setMockFiles mock_file_info. ;
} ;
测试 '包括摘要中目录中的所有文件' = > {
const FileSummarizer = 要求 '../filesummarizer' ;
const 文件ummary. = FileSummarizer summarizeFilesInDirectorySync
'/ path /'
;
预计 文件ummary. 长度 成为 2 ;
} ;
} ;

这里显示的示例mock使用jest.genmockfrommodule.要生成自动模拟,并覆盖其默认行为。这是推荐的方法,但完全可选。如果您不想ally使用自动模拟,则可以从模拟文件导出自己的函数。完全手动模拟的一个缺点是它们是手动 - 这意味着您必须在它们嘲笑更改的模块时手动更新它们。因此,它最好使用或延长自动模拟时,它适用于您的需求。

为确保手动模拟及其实际实现保持同步,可能需要使用实体模块Jest.requireAcctual(Modulename)在您的手动模拟中,在导出之前用模拟函数修改它。

这个例子的代码可以在下面找到例子/ manual-mocks

使用ES模块导入

如果你使用了ES模块进口那么你通常会倾向于把你的进口测试文件顶部的语句。但通常需要在模块使用mock之前指示Jest使用mock。因此,Jest会自动提升jest.mock.调用模块的顶部(在任何导入之前)。要了解更多信息并查看它的实际操作,请参见这个回购

嘲弄方法在JSDOM中未实施

如果某些代码使用jsdom(Jest使用的DOM实现)的方法尚未实现,则无法轻易测试。这是如此。这种情况window.matchmedia()。Jest的回报typeerror:window.matchmedia不是函数并且没有正确执行测试。

在这种情况下,嘲笑匹配媒体在测试文件中应该解决问题:

目的 defineproperty. 窗户 “matchMedia” {
可写的 真正的
价值 笑话 FN. mockImplementation 询问 = > {
火柴 错误的
媒体 询问
onchange.
AddListener. 笑话 FN. //弃用
removelistener. 笑话 FN. //弃用
addeventlistener. 笑话 FN.
RemoveeventListener. 笑话 FN.
DispatchEvent. 笑话 FN.
}
} ;

这是适用的window.matchmedia()在测试中调用的函数(或方法)中使用。如果window.matchmedia()直接在测试文件中执行,Jest报告相同的错误。在这种情况下,解决方案是将手动模拟移动到单独的文件中,并在测试中包含此一个之前测试文件:

进口 './matchmedia.mock' ; //必须在测试文件之前导入
进口 { myMethod } './file-to-test' ;
描述 “myMethod()” = > {
//测试该方法...
} ;
最后一次更新在经过raj rajhans.