2016-07-12 6 views
15

Предположим, что у меня есть следующий модуль:Как я могу издеваться над require.context Webpack в Jest?

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

Jest жалуется, потому что он не знает о 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

Но если это действительно необходимо, вы должны включать в себя polyfill ниже в каждом файле, который вы называете его (а не на самих тестах, потому что require не будет глобально переопределен в среде Node).

// 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, используя оригинал, и если в Jest с издевались функции).

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

Очень хорошо. Но если мне действительно нужны исходные модули для включения? Я предполагаю, что единственный побег использует мою реализацию в ответе (что тоже не идеально). ИМО, я по-прежнему считаю, что лучше всего прекратить использовать его. –

Смежные вопросы