跳转到主要内容
版本:26.倍

手动Pentru Dubluri.

模拟尿样的folfolsite pentru înlocui funcţionalități cu日期模拟。举个例子,în loc să accesați o resursă din rețea precum un site sau o bază De date, aţi putea dori să creați un mock manual care vă permite să utilizaţi date false。Acest lucu asigură că testele vor fi rapide şi nu fragile。

模拟用户模块#

Mock-urile手册必须确定unui模块în子目录__mocks__ /imediat adiacence modulului。de presseu,pentru crea un mock pentru联合国modul numit用户在directorul模型, creaţi UN fişier numituser.js.şiPuneţi-lîn导演模型/ __模仿__。再保险ţ我ţcăfolderul__mocks__Este Case-Cantitive,Astfelîncâtdenumirea__MOCKS__Nu va funcționa PE unele sisteme。

当我们在测试中要求该模块时,明确地呼叫jest.mock (' / moduleName’)。要求

模拟节点模块#

如果您嘲笑的模块是节点模块(例如:lodash), mock应放在__mocks__邻近的目录node_modules(除非你配置指向项目根目录以外的文件夹),将是自动嘲笑。没有必要明确地打电话jest.mock(“module_name”)

作用域模块(也称为范围包装)可以通过在与范围名称的目录结构中创建文件来嘲笑。例如,要模拟一个调用的范围模块@scope /项目名称,创建文件__mocks__/@scope/project-name.js.,形成了@范围/相应的目录。

警告:如果我们想模拟Node的核心模块(例如:fs或者路径),然后显式调用。jest.mock(路径)要求,因为核心Node模块在默认情况下不会被嘲弄。

ex#

├──配置
├──__mocks__
│└──fs.js.
├──模型
│├──__mocks__
││├─cat sound效果器整理www.catsound.js
│└──user.js.
├──node_modules
└──观点

Atunci când un mock manual există pentru un anumit module, sistemul de module din est va utiza acel module când apelați explicitjest.mock('modulename')。但是,当automock设定为真的,将使用手动模拟实现而不是自动创建的模拟,即使jest.mock('modulename')不被称为。Pentrurenunţala母版comportame trebuie s hiapelaţi明确jest.unmock(“moduleName”)întestele carear artbuisōultizeimementareatemon一个modulului。

注意:为了适当地嘲笑,Jest需要jest.mock('modulename')与之相同的范围要求/导入陈述。

这里有一个人为的例子,其中我们有一个模块,它提供了给定目录中所有文件的摘要。在本例中,我们使用内核(内置的)fs模块。

// filesummarizer.js.
使用严格的 ;
常量 fs = 需要 ( 'FS' ) ;
功能 summarizefilesindirectorysync. ( 目录 ) {
返回 fs readdirSync ( 目录 ) 地图 ( 文件名 => ( {
目录 ,
文件名 ,
} ) ) ;
}
出口 summarizefilesindirectorysync. = summarizefilesindirectorysync. ;

由于我们希望尝试避免实际击中磁盘(这非常缓慢而脆弱),我们为此创建了手动模拟fs模块通过扩展自动模拟。我们的手动模拟将实现自定义版本fs我们可以构建用于测试的api:

// __mocks __ / fs.js
使用严格的 ;
常量 路径 = 需要 ( “路径” ) ;
常量 fs = 开玩笑 createMockFromModule ( 'FS' ) ;
//这是一个自定义函数,我们的测试可以在设置期间使用
//模拟文件系统上的文件应该是什么样子
//使用' fs ' api。
mockFiles = 对象 创造 ( 空值 ) ;
功能 __setmockfiles. ( newMockFiles ) {
mockFiles = 对象 创造 ( 空值 ) ;
( 常量 文件 newMockFiles ) {
常量 dir = 路径 目录名 ( 文件 ) ;
如果 ( ! mockFiles ( dir ] ) {
mockFiles ( dir ] = ( ] ;
}
mockFiles ( dir ] ( 路径 Basename. ( 文件 ) ) ;
}
}
//从特殊模型中读取的“readdirsync`的自定义版本”
//通过__setmockfiles设置文件列表
功能 readdirSync ( 目录路径 ) {
返回 mockFiles ( 目录路径 ] || ( ] ;
}
fs __setmockfiles. = __setmockfiles. ;
fs readdirSync = readdirSync ;
模块 出口 = fs ;

现在我们编写测试。注意,我们需要显式地告诉fs因为它是一个核心Node模块:

// __tests __ / filesummarizer-test.js
使用严格的 ;
开玩笑 嘲笑 ( 'FS' ) ;
描述 ( “listFilesInDirectorySync” , ( ) => {
常量 MOCK_FILE_INFO = {
“/道路/ / file1.js” : “console.log(“file1内容”),“ ,
“/道路/ / file2.txt” : 'file2内容' ,
} ;
beforeEach ( ( ) => {
//在每次测试前设置一些模拟文件信息
需要 ( 'FS' ) __setmockfiles. ( MOCK_FILE_INFO ) ;
} ) ;
测试 ( “包含摘要目录中的所有文件” , ( ) => {
常量 filesumarizer = 需要 ( “. . / FileSummarizer” ) ;
常量 fileSummary = filesumarizer summarizefilesindirectorysync. (
' /路径/ ' ,
) ;
预计 ( fileSummary 长度 ) 托比 ( 2 ) ;
} ) ;
} ) ;

这里显示的示例模拟使用jest.createmockfrommodule.生成一个自动模拟,并覆盖其默认行为。这是推荐的方法,但完全是可选的。如果您根本不想使用自动模拟,您可以从模拟文件导出您自己的函数。完全手动模拟的一个缺点是它们是手动的——这意味着您必须在它们模拟的模块发生变化时手动更新它们。因此,最好在自动模拟能够满足您的需求时使用或扩展它。

为了确保手动模拟和它的实际实现保持同步,可能需要使用实际模块jest.requireActual (moduleName)在您的手动模拟和在导出它之前用模拟函数修改它。

此示例的代码可用示例/手动模拟

Folosirea cu importurile modulelor ES#

如果您正在使用ES模块导入那你通常会倾向于把你的进口测试文件顶部的语句。但是,通常需要指示Jest在模块使用之前使用模拟。因此,Jest将自动提升jest.mock调用模块顶部(在任何导入之前)。要了解更多有关此功能,请参阅这种回购

模拟没有在JSDOM中实现的方法#

如果一些代码使用了JSDOM (Jest使用的DOM实现)还没有实现的方法,那么测试它就不容易。这是一个例子window.matchMedia ()。jest回报TypeError:窗口。matchMedia是not a function并且不能正确地执行测试。

在这里,是嘲笑matchMedia在测试文件中应该解决的问题:

对象 defineProperty ( 窗口 , 'matchmedia' , {
可写的 : 真的 ,
价值 : 开玩笑 fn ( ) 模仿 ( 查询 => ( {
匹配 : ,
媒体 : 查询 ,
onchange : 空值 ,
addListener : 开玩笑 fn ( ) , / /弃用
removeListener : 开玩笑 fn ( ) , / /弃用
addEventListener : 开玩笑 fn ( ) ,
removeEventListener : 开玩笑 fn ( ) ,
dispatchEvent : 开玩笑 fn ( ) ,
} ) ) ,
} ) ;

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

进口 ”。/ matchMedia.mock ' ; //必须在测试文件之前导入
进口 { 迈运 } ”。/ file-to-test ' ;
描述 ( 'mymethod()' , ( ) => {
//在这里测试方法…
} ) ;