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

モック関数

モック関数によりコード間の繋がりをテストすることができます。関数が持つ実際の実装を除去したり,関数の呼び出し(また,呼び出しに渡されたパラメータも含め)をキャプチャしたり,によるコンストラクタ関数のインスタンス化をキャプチャできます。そうすることでテスト時のみの返り値の設定をすることが可能になります。

関数をモックするには,次の2つの方法があります。1つは,テストコードの中でモック関数を作成するという方法。もう1つは,<一个href="//www.ieatrice.com/ja/docs/manual-mocks">人工模拟を作成してモジュールの依存性を上書きするという方法です。

モック関数を利用する<一个类="hash-link" href="#モック関数を利用する" title="#">#

forEach関数の実装をテストすることを考えてみましょう。この関数は,与えられた配列の各要素に対して,コールバック関数を呼び出します。

函数 forEach ( 项目 , 回调 ) {
( 指数 = 0 ; 指数 < 项目 长度 ; 指数 ++ ) {
回调 ( 项目 ( 指数 ] ) ;
}
}

この関数をテストするために,モック関数を利用して,コールバックが期待通り呼び出されるかを確認するためにモックの状態を検証することができます。

常量 mockCallback = 开玩笑 fn ( x = > 42 + x ) ;
forEach ( ( 0 , 1 ] , mockCallback ) ;
//模拟函数被调用两次
预计 ( mockCallback 模拟 调用 长度 ) 托比 ( 2 ) ;
//函数第一次调用的第一个参数为0
预计 ( mockCallback 模拟 调用 ( 0 ] ( 0 ] ) 托比 ( 0 ) ;
//第二个函数调用的第一个参数是1
预计 ( mockCallback 模拟 调用 ( 1 ] ( 0 ] ) 托比 ( 1 ) ;
//第一次调用函数的返回值是42
预计 ( mockCallback 模拟 结果 ( 0 ] 价值 ) 托比 ( 42 ) ;

.mockプロパティ<一个类="hash-link" href="#mock-プロパティ" title="#">#

すべてのモック関数には,この特別な.mockプロパティがあり,モック関数呼び出し時のデータと,関数の返り値が記録されています。.mockプロパティには,各呼び出し時のの値も記録されているため,の値のチェックも可能です。

常量 myMock = 开玩笑 fn ( ) ;
常量 一个 = myMock ( ) ;
常量 b = { } ;
常量 绑定 = myMock 绑定 ( b ) ;
绑定 ( ) ;
控制台 日志 ( myMock 模拟 实例 ) ;
// > []

以下のモックのプロパティを使用すると,関数がどのように呼び出され,どのようにインスタンス化され,返り値が何であったのかを確認することができます。

/ /函数はちょうど1回だけ呼ばれた
预计 ( someMockFunction 模拟 调用 长度 ) 托比 ( 1 ) ;
/ /関数の1回目の呼び出しの1番目の引数は“第一arg”だった
预计 ( someMockFunction 模拟 调用 ( 0 ] ( 0 ] ) 托比 ( 的第一个参数 ) ;
/ /関数の1回目の呼び出しの2番目の引数は“第二arg”だった
预计 ( someMockFunction 模拟 调用 ( 0 ] ( 1 ] ) 托比 ( 第二个参数的 ) ;
/ /関数の1回目の呼び出しの返り値は“返回值”だった
预计 ( someMockFunction 模拟 结果 ( 0 ] 价值 ) 托比 ( “返回值” ) ;
/ /この関数はちょうど2回インスタンス化された
预计 ( someMockFunction 模拟 实例 长度 ) 托比 ( 2 ) ;
/ /この関数の1回目のインスタンス化で返されたインスタンスは,
/ /“名字”プロパティを持っており,その値は'测试'であった
预计 ( someMockFunction 模拟 实例 ( 0 ] 的名字 ) toEqual ( “测试” ) ;

モックの戻り値<一个类="hash-link" href="#モックの戻り値" title="#">#

モック関数は,テスト中のコードにテスト用の値を注入するのにも利用できます。

常量 myMock = 开玩笑 fn ( ) ;
控制台 日志 ( myMock ( ) ) ;
/ / >定义
myMock mockReturnValueOnce ( 10 ) mockReturnValueOnce ( “x” ) mockReturnValue ( 真正的 ) ;
控制台 日志 ( myMock ( ) , myMock ( ) , myMock ( ) , myMock ( ) ) ;
// 10, 'x', true, true

モック関数は,関数的な継続渡し(连续的传递)のスタイルを利用したコードでも,とても効果的です。コードをこのスタイルで書くことで,本物のコンポーネントの振る舞いを再現するような複雑なスタブが必要になることを避けることができ,テストで使われる直前に値を直接注入するができるようになります。

常量 filterTestFn = 开玩笑 fn ( ) ;
//为第一次调用模拟返回' true ',
//和' false '为第二个调用
filterTestFn mockReturnValueOnce ( 真正的 ) mockReturnValueOnce ( ) ;
常量 结果 = ( 11 , 12 ] 过滤器 ( 全国矿工工会 = > filterTestFn ( 全国矿工工会 ) ) ;
控制台 日志 ( 结果 ) ;
/ / > [11]
控制台 日志 ( filterTestFn 模拟 调用 ) ;
// > [[11], [12]]

実世界のほとんどの例では,依存しているコンポーネントのモック関数を見つけ出して構成することが必要となりますが,テクニック自体は一緒です。こうしたテストを書く場合は,関数の内の直接テストされていないロジックを実装したくなる誘惑を避けるように努めましょう。

モジュールのモック<一个类="hash-link" href="#モジュールのモック" title="#">#

APIからユーザーを取得するクラスがあるとします。以下のクラスは,<一个href="https://github.com/axios/axios" target="_blank" rel="noopener noreferrer">axiosを使用してAPIを呼び,全てのユーザーが持っている数据属性を返します。

/ / users.js
进口 axios “axios” ;
用户 {
静态 所有 ( ) {
返回 axios 得到 ( ' / users.json ' ) 然后 ( 分别地 = > 分别地 数据 ) ;
}
}
出口 默认的 用户 ;

さて,このメソッドを実際にAPIにアクセスせずにテストするために(もしそのようなテストを作れば,遅くて壊れやすいテストになってしまいます),jest.mock(…)関数を使えば,axiosモジュールを自動的にモックすることができます。

一度モジュールをモックすれば,. getに対してmockResolvedValueメソッドを使えるようになり,テストで検証したいデータを返させるようにできます。实际上,我们是在说我们想要axios.get (' / users.json ')返回一个假响应。

/ / users.test.js
进口 axios “axios” ;
进口 用户 ”。/用户的 ;
开玩笑 模拟 ( “axios” ) ;
测试 ( “应该获取用户的 , ( ) = > {
常量 用户 = ( { 的名字 : “鲍勃” } ] ;
常量 分别地 = { 数据 : 用户 } ;
axios 得到 mockResolvedValue ( 分别地 ) ;
//根据你的用例,你可以使用以下方法:
// axios.get.mockImplementation(() => Promise.resolve(resp))
返回 用户 所有 ( ) 然后 ( 数据 = > 预计 ( 数据 ) toEqual ( 用户 ) ) ;
} ) ;

モックの実装<一个类="hash-link" href="#モックの実装" title="#">#

とはいえ,指定された値を返すという能力を越えて完全に実装をモック化することが便利なケースがあります。これはjest.fnまたはモック関数のmockImplementationOnceメソッドを利用することで実現できます。

常量 myMockFn = 开玩笑 fn ( cb = > cb ( , 真正的 ) ) ;
myMockFn ( ( 犯错 , 瓦尔 ) = > 控制台 日志 ( 瓦尔 ) ) ;
/ / >真

mockImplementationメソッドは他のモジュールによって作成されたモック関数のデフォルトの実装を定義したいときに便利です。

/ / foo.js
模块 出口 = 函数 ( ) {
/ /一些实现;
} ;
/ / . js
开玩笑 模拟 ( “. . / foo” ) ; //通过automocking自动实现
常量 喷火 = 需要 ( “. . / foo” ) ;
// foo是一个mock函数
喷火 mockImplementation ( ( ) = > 42 ) ;
喷火 ( ) ;
/ / > 42

関数への複数回への呼び出しで異なる結果を得るように複雑な挙動をするモック関数を再作成する必要がある場合はmockImplementationOnceメソッドを使用して下さい。

常量 myMockFn = 开玩笑
fn ( )
mockImplementationOnce ( cb = > cb ( , 真正的 ) )
mockImplementationOnce ( cb = > cb ( , ) ) ;
myMockFn ( ( 犯错 , 瓦尔 ) = > 控制台 日志 ( 瓦尔 ) ) ;
/ / >真
myMockFn ( ( 犯错 , 瓦尔 ) = > 控制台 日志 ( 瓦尔 ) ) ;
/ / >假

モック関数がmockImplementationOnceによって定義された実装が全て使い切った時は,(もし定義されていれば)jest.fnのデフォルトの実装を実行します。

常量 myMockFn = 开玩笑
fn ( ( ) = > “默认” )
mockImplementationOnce ( ( ) = > “第一个电话” )
mockImplementationOnce ( ( ) = > “第二个电话” ) ;
控制台 日志 ( myMockFn ( ) , myMockFn ( ) , myMockFn ( ) , myMockFn ( ) ) ;
// > 'first call', 'second call', 'default', 'default'

よくチェーンされる(そしてのために常にを返す必要のある)メソッドがあるケースのために,この実装を単純化する糖を衣API.mockReturnThis ()の形で全てのモックが備えています。

常量 myObj = {
myMethod : 开玩笑 fn ( ) mockReturnThis ( ) ,
} ;
//等于
常量 otherObj = {
myMethod : 开玩笑 fn ( 函数 ( ) {
返回 ;
} ) ,
} ;

モック名<一个类="hash-link" href="#モック名" title="#">#

您可以选择为模拟函数提供一个名称,该名称将在测试错误输出中显示,而不是“jest.fn()”。テスト結果でエラーを出力しているモック関数を迅速に特定したい場合に使用します。

常量 myMockFn = 开玩笑
fn ( )
mockReturnValue ( “默认” )
mockImplementation ( 标量 = > 42 + 标量 )
mockName ( “add42” ) ;

カスタムマッチャ<一个类="hash-link" href="#カスタムマッチャ" title="#">#

最後にモック関数がどのように呼ばれたかを検査する必要を減らすため,いくつかのカスタムマッチャを用意しておきました。

// mock函数至少被调用一次
预计 ( mockFunc ) toHaveBeenCalled ( ) ;
//使用指定的参数至少调用一次模拟函数
预计 ( mockFunc ) toHaveBeenCalledWith ( __arg1 , 最长 ) ;
//最后一次调用模拟函数是使用指定的参数调用的
预计 ( mockFunc ) toHaveBeenLastCalledWith ( __arg1 , 最长 ) ;
//所有调用和mock的名称都被写入快照
预计 ( mockFunc ) toMatchSnapshot ( ) ;

これらのマッチャは.mockプロパティを検査する一般的な方法の糖衣構文です。より好みに合うものが欲しい場合や,より特定のテストに向けたものが必要な場合は,いつでも手動でカスタムマッチャを追加することができます。

// mock函数至少被调用一次
预计 ( mockFunc 模拟 调用 长度 ) toBeGreaterThan ( 0 ) ;
//使用指定的参数至少调用一次模拟函数
预计 ( mockFunc 模拟 调用 ) toContainEqual ( ( __arg1 , 最长 ] ) ;
//最后一次调用模拟函数是使用指定的参数调用的
预计 ( mockFunc 模拟 调用 ( mockFunc 模拟 调用 长度 - 1 ] ) toEqual ( (
__arg1 ,
最长 ,
] ) ;
//最后一次调用mock函数的第一个参数是“42”
//(注意,对于这个特定的断言没有糖助手)亚搏取款
预计 ( mockFunc 模拟 调用 ( mockFunc 模拟 调用 长度 - 1 ] ( 0 ] ) 托比 ( 42 ) ;
//一个快照将检查一个mock被调用的次数是否相同,
//以相同的顺序,使用相同的参数。它还将对名称进行断言。
预计 ( mockFunc 模拟 调用 ) toEqual ( ( ( __arg1 , 最长 ] ] ) ;
预计 ( mockFunc getMockName ( ) ) 托比 ( “一个模拟的名字” ) ;

マッチャーの完全なリストについては,<一个href="/ja/docs/expect">リファレンスドキュメントを確認してください。