2016-07-12 267 views
15

假設我有以下模塊:如何在Jest中模擬Webpack的require.context?

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

玩笑抱怨,因爲它不知道require.context

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

我怎麼能嘲笑呢?我嘗試使用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

非常好。但是如果我實際上需要包含原始模塊?我想唯一的解決辦法就是在答案中使用我的實現(這也不完美)。國際海事組織,我仍然認爲最好的選擇是停止使用它。 –