2016-07-12 8 views
15

私は、次のモジュールがあるとします。Webpackのrequire.contextをJestでモックするにはどうしたらいいですか?

FAIL /foo/bar.spec.js (0s) 
● Runtime Error 
    - TypeError: require.context is not a function 

どのように私はそれを模擬することができます:それはおよそrequire.contextを知らないので、

var modulesReq = require.context('.', false, /\.js$/); 
modulesReq.keys().forEach(function(module) { 
    modulesReq(module); 
}); 

冗談は不平を言いますか? setupTestFrameworkScriptFile Jest設定を試してみましたが、requireで行った変更をテストで確認することはできません。

+0

あなたの答えは見つかりましたか? – BigDong

答えて

4

私は同じ問題を抱えていましたが、私は「解決策」を作りました。

私はこれが最良の選択ではないと確信しています。 、

https://github.com/facebookincubator/create-react-app/issues/517 https://github.com/facebook/jest/issues/2298

しかし、実際にそれを必要とする場合、あなたはあなたがいないテスト自体に(それを呼び出すすべてのファイルに以下のポリフィルを含める必要があります。私はここで答えたポイントで、それを使用してストーピングを終わりましたrequireはノード環境でグローバルオーバーライドされないため)。この機能を

// This condition actually should detect if it's an Node environment 
if (typeof require.context === 'undefined') { 
    const fs = require('fs'); 
    const path = require('path'); 

    require.context = (base = '.', scanSubDirectories = false, regularExpression = /\.js$/) => { 
    const files = {}; 

    function readDirectory(directory) { 
     fs.readdirSync(directory).forEach((file) => { 
     const fullPath = path.resolve(directory, file); 

     if (fs.statSync(fullPath).isDirectory()) { 
      if (scanSubDirectories) readDirectory(fullPath); 

      return; 
     } 

     if (!regularExpression.test(fullPath)) return; 

     files[fullPath] = true; 
     }); 
    } 

    readDirectory(path.resolve(__dirname, base)); 

    function Module(file) { 
     return require(file); 
    } 

    Module.keys =() => Object.keys(files); 

    return Module; 
    }; 
} 

、あなたはどんなrequire.context呼び出しを変更する必要はありません、それは(嘲笑機能で、WebPACKの上にある場合は、オリジナルを使用して、そしてもし冗談で)同じ動作で実行されます。

5

別のモジュールへの呼び出しを抽出します。

// src/js/lib/bundle-loader.js 
/* istanbul ignore next */ 
module.exports = require.context('bundle-loader?lazy!../components/', false, /.*\.vue$/) 

は、あなたがからそれを抽出したモジュールで新しいモジュールを使用します。

// src/js/lib/loader.js 
const loadModule = require('lib/bundle-loader') 
// ... 

新しく作成されたバンドル・ローダーモジュールのモックを作成します。 :

// test/unit/specs/__mocks__/lib/bundle-loader.js 
export default() =>() => 'foobar' 

は、あなたのテストでモックを使用します。

// test/unit/specs/lib/loader.spec.js 
jest.mock('lib/bundle-loader') 
import Loader from 'lib/loader' 

describe('lib/loader',() => { 
    describe('Loader',() => { 
    it('should load',() => { 
     const loader = new Loader('[data-module]') 
     expect(loader).toBeInstanceOf(Loader) 
    }) 
    }) 
}) 
+0

非常に良い。しかし、実際に元のモジュールを組み込む必要があるのですか?私は唯一のエスケープは答えに自分の実装を使用していると思います(これも完璧ではありません)。 IMO、私は最良の選択は、それを使用を停止することです残っている。 –

関連する問題