別のファイルで定義されている関数(funA)を呼び出そうとしていますが、この関数は内部的に同じファイル内の別の関数(funB)を呼び出します。
ここで、funA の呼び出し数を取得しようとすると、正しい結果が得られます。ただし、funB には同じことが当てはまらず、呼び出しカウントは常に 0 を返します。
これが私のコードです:
ファイルB
function funB() {
}
function funA() {
funB();
}
module.exports = {funA, funB}
ファイルA
import * as fileB from "/path/to/fileB";
sinon.spy(fileB);
fileB.funA();
fileB.funA.callCount // returns 1;
fileB.funB.callCount // returns 0; // expected 1
sinon.restore();
ここで私が間違っていることは何ですか。
インポートに問題があるのでしょうか。require キーワードを使用してインポートしようとしましたが、それも機能しないようです。
funA が呼び出されるたびに、funB が適切なパラメータで呼び出されることを確認する必要があります。
どうすればそれを達成できますか。
------------------------
ここでの問題は、sinon.spy が fileA 内の関数にのみスパイを設定しているという事実によるものだと思います。これは、モジュールのロード方法が原因です。
ファイルがロードされる順序を考慮してください。
ファイルAをロードする
fileB からインポートする - これにはノードが fileB をロードしてすべてを設定する必要があります
ファイルBの関数にスパイを設定する
ここで重要なステップは #2 です。 fileB がロードされ、すべてのシンボルが解決された時点では、スパイはまだセットアップされていません。したがって、funA の途中にある funB への参照は、単なる古い funB への参照であり、「スパイされた」ものではありません。バージョン。そして、あなたは「スパイ」と呼んでいますが、 funA のバージョンには、funB の元の値への参照が含まれており、それが呼び出されます。
要するにt、sinon は、すでに作成された参照に戻って書き直すことはしません (またできません)。そのため、funB への参照は sinon.spy の呼び出しの影響を受けません。
両方の関数が同じファイル内にあるため、funB をスパイすることはできません。解決策の 1 つは、プロジェクトを別のファイルに配置するように再構築することです。これにより、初期化する前にスパイをセットアップできるようになります。別の解決策は、テストを実行する前に funB のスパイ/スタブ バージョンを挿入できるようにファイルを設定することです。
------------------------
コードでは、funA は常に元の funB を呼び出します。
別の方法があります。object を使用して fileB の実装を変更します。
例:
// File: fileB
// Create object fileB.
const fileB = {
funB() {},
funA() {
// Note: funA calls method funB inside object fileB.
fileB.funB();
},
}
module.exports = fileB;
// File: fileA
import sinon from 'sinon';
import fileB from './fileB';
// This spy will replace all method in the object with wrapped original method.
sinon.spy(fileB);
// You call spied funA, which will call spied funB.
fileB.funA();
console.log(fileB.funA.callCount); // returns 1;
console.log(fileB.funB.callCount); // returns 0; // expected 1
sinon.restore();
結果:
$ npx mocha fileA.js
1
1
0 passing (0ms)
$