2016-07-12 49 views
15

Supponiamo che io ho il seguente modulo:Come posso schernire require.context di Webpack in Jest?

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

Jest si lamenta perché non sa di require.context:

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

Come posso prendere in giro vero? Ho provato a utilizzare la configurazione Jest setupTestFrameworkScriptFile ma i test non sono in grado di visualizzare le modifiche apportate in require.

+0

Hai trovato la risposta? – BigDong

risposta

4

Ho avuto lo stesso problema, quindi faccio una "soluzione".

Sono abbastanza sicuro che questa non è la scelta migliore. Ho finito per stoping usarlo, dai punti di risposta qui:

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

Ma se davvero bisogno, è necessario includere l'ovatta di seguito in ogni file che si chiama (non sulle prove stesso, perché lo require non sarà sovrascritto a livello globale in un ambiente nodo).

// 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; 
    }; 
} 

Con questa funzione, non è necessario cambiare qualsiasi require.context chiamata, si esegue con lo stesso comportamento (se è in webpack, utilizzando l'originale, e se per scherzo, con la funzione deriso).

5

Estrarre la chiamata a un modulo separato:

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

Utilizzare il nuovo modulo nel modulo di cui è stato estratto da:

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

Creare un mock per il modulo fascio-loader di nuova creazione :

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

Utilizzare il mock nel test:

// 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

Molto buono. Ma se sono effettivamente necessari i moduli originali da includere? Immagino che l'unica via d'uscita sia usare la mia implementazione nella risposta (che non è perfetta anche per me). IMO, rimango che la scelta migliore è smettere di usarlo. –

Problemi correlati