219

nodejsで内部(つまり、エクスポートされていない)関数をテストする方法を理解しようとしています(できればモカまたはジャスミンを使用)。そして、私にはわかりません!

そのようなモジュールがあるとしましょう:

function exported(i) {
   return notExported(i) + 1;
}

function notExported(i) {
   return i*2;
}

exports.exported = exported;

そして、次のテスト(モカ):

var assert = require('assert'),
    test = require('../modules/core/test');

describe('test', function(){

  describe('#exported(i)', function(){
    it('should return (i*2)+1 for any given i', function(){
      assert.equal(3, test.exported(1));
      assert.equal(5, test.exported(2));
    });
  });
});

notExported公開することを意図していないため、実際にエクスポートせずに関数を単体テストする方法はありますか?

4

10 に答える 10

17

トリックは、NODE_ENV環境変数を次のように設定しtest、条件付きでエクスポートすることです。

mocha をグローバルにインストールしていないと仮定すると、次を含むアプリ ディレクトリのルートに Makefile を作成できます。

REPORTER = dot

test:
    @NODE_ENV=test ./node_modules/.bin/mocha \
        --recursive --reporter $(REPORTER) --ui bbd

.PHONY: test

この make ファイルは、mocha を実行する前に NODE_ENV を設定します。make testその後、コマンド ラインでmocha テストを実行できます。

これで、mocha テストの実行時にのみ通常はエクスポートされない関数を条件付きでエクスポートできるようになりました。

function exported(i) {
   return notExported(i) + 1;
}

function notExported(i) {
   return i*2;
}

if (process.env.NODE_ENV === "test") {
   exports.notExported = notExported;
}
exports.exported = exported;

他の回答では、vm モジュールを使用してファイルを評価することを提案しましたが、これは機能せず、エクスポートが定義されていないというエラーがスローされます。

于 2013-10-13T10:15:05.213 に答える
0

テスト内からこれらの内部関数をテスト、スパイ、およびモックできる非常に簡単な方法を見つけました。

次のようなノード モジュールがあるとします。

mymodule.js:
------------
"use strict";

function myInternalFn() {

}

function myExportableFn() {
    myInternalFn();   
}

exports.myExportableFn = myExportableFn;

本番環境にエクスポートせずに、テストスパイ、およびモックを行いたい場合は、次のようにファイルを改善する必要があります。myInternalFn

my_modified_module.js:
----------------------
"use strict";

var testable;                          // <-- this is new

function myInternalFn() {

}

function myExportableFn() {
    testable.myInternalFn();           // <-- this has changed
}

exports.myExportableFn = myExportableFn;

                                       // the following part is new
if( typeof jasmine !== "undefined" ) {
    testable = exports;
} else {
    testable = {};
}

testable.myInternalFn = myInternalFn;

myInternalFnこれで、使用する場所ならどこでもテスト、スパイ、およびモックを作成できtestable.myInternalFn、本番環境ではエクスポートされません

于 2014-10-23T07:03:01.153 に答える
0

repl のように、vmモジュールを使用して新しいコンテキストを作成し、その中の js ファイルを評価できます。その後、宣言されているすべてのものにアクセスできます。

于 2013-02-14T19:59:10.877 に答える
0

rewireこれは推奨される方法ではありませんが、@Antoine の提案どおりに使用できない場合は、いつでもファイルを読み取って を使用できますeval()

var fs = require('fs');
const JsFileString = fs.readFileSync(fileAbsolutePath, 'utf-8');
eval(JsFileString);

これは、レガシー システムのクライアント側 JS ファイルを単体テストする際に役立つことがわかりました。

JS ファイルは、 andステートメントwindowなしで多くのグローバル変数をセットアップします(いずれにせよ、これらのステートメントを削除できる Webpack や Browserify のようなモジュール バンドラーはありませんでした)。require(...)module.exports

これにより、コードベース全体をリファクタリングするのではなく、クライアント側の JS に単体テストを統合することができました。

于 2018-07-25T12:32:03.363 に答える
0

基本的に、ソース コンテキストをテスト ケースとマージする必要があります。これを行う 1 つの方法は、テストをラップする小さなヘルパー関数を使用することです。

デモ.js

const internalVar = 1;

demo.test.js

const importing = (sourceFile, tests) => eval(`${require('fs').readFileSync(sourceFile)};(${String(tests)})();`);


importing('./demo.js', () => {
    it('should have context access', () => {
        expect(internalVar).toBe(1);
    });
});

于 2020-11-21T11:17:10.067 に答える