2015-11-19 9 views
42

Ich entwickle eine Web-App bei React/Redux/Webpack und fange jetzt an, Tests mit Mocha zu integrieren.Verwendung von Webpack-Aliases in Mocha-Tests

Ich folgte the instructions for writing tests in the Redux documentation, aber jetzt habe ich ein Problem mit meinem Webpack-Aliase.

Nehmen wir zum Beispiel einen Blick auf die Einfuhren Abschnitt dieser Test für einen meiner Aktion Schöpfer:

import expect  from 'expect'     // resolves without an issue 
import * as actions from 'actions/app';   // can't resolve this alias 
import * as types from 'constants/actionTypes'; // can't resolve this alias 

describe('Actions',() => { 
    describe('app',() => { 
    it('should create an action with a successful connection',() => { 

     const host = '***************', 
      port = ****, 
      db = '******', 
      user = '*********', 
      pass = '******'; 

     const action = actions.createConnection(host, port, db, user, pass); 

     const expectedAction = { 
     type: types.CREATE_CONNECTION, 
     status: 'success', 
     payload: { host, port, database, username } 
     }; 

     expect(action).toEqual(expectedAction); 
    }); 
    }); 
}); 

Da die Kommentare deuten darauf hin, Mokka ist nicht in der Lage meine Import-Anweisungen zu lösen, wenn sie verweisen Alias-Abhängigkeiten.

Weil ich noch neu in webpack bin, hier meine webpack.config.js:

module.exports = { 
    devtool: 'eval-source-map', 
    entry: [ 
    'webpack-hot-middleware/client', 
    './src/index' 
    ], 
    output: { 
    path: path.join(__dirname, 'dist'), 
    filename: 'bundle.js', 
    publicPath: '/static/' 
    }, 
    resolve: { 
    extensions : ['', '.js', '.jsx'], 
    alias: { 
     actions: path.resolve(__dirname, 'src', 'actions'), 
     constants: path.resolve(__dirname, 'src', 'constants'), 
     /* more aliases */ 
    } 
    }, 
    plugins: [ 
    new webpack.optimize.OccurenceOrderPlugin(), 
    new webpack.HotModuleReplacementPlugin(), 
    new webpack.NoErrorsPlugin() 
    ], 
    module: { 
    loaders: [{ 
     test: /\.js$/, 
     loaders: ['babel'], 
     exclude: /node_modules/, 
     include: __dirname 
    }] 
    } 
}; 

Auch ich bin mit dem Befehl npm test Mokka zu laufen, hier ist das Skript, das ich in meinem package.json bin mit.

{ 
    "scripts": { 
    "test": "mocha ./src/**/test/spec.js --compilers js:babel-core/register --recursive" 
    } 
} 

Also hier ist, wo ich stecken bleibe. Ich muss die Aliase von Webpack in Mocha einschließen, wenn es ausgeführt wird.

+0

ich das gleiche Problem haben, haben Sie gefunden, einen Weg, dies zu tun? –

+0

Ja, habe gerade meine Antwort gepostet. YMMV –

Antwort

33

Okay, ich erkannte, dass alles, was ich Aliasing war in der src/ Verzeichnis, so dass ich einfach meine npm run test Skript ändern musste.

Wahrscheinlich wird nicht für alle arbeiten, aber das hat mein Problem gelöst.

+0

Danke, ich werde es versuchen. –

+0

Alle meine Sachen sind auch in 'src', aber nicht sicher, wie Sie Ihren Fix in mein Testskript implementieren:' find ./src -name '* .test.js' | xargs mocha --require babel-core/register' – azium

+0

Dies ist eine sehr gute Lösung, vor allem im Vergleich zu Mocking und Proxying erfordern !! – mikeycgto

1

Ich hatte genau das gleiche Problem. Es scheint unmöglich zu sein, Webpack-Aliase in require.js oder in Knoten zu verwenden.

landete ich mit mock-require in den Unit-Tests und ersetzt nur die Pfade manuell, wie folgt aus:

var mock = require('mock-require'); 

mock('actions/app', '../../src/actions/app'); 

Mock-erfordern ein gutes Werkzeug ist, weil die meisten wahrscheinlich, dass Sie die meisten Ihrer verspotten möchten Abhängigkeiten, anstatt die eigentlichen Skripte von src zu verwenden.

+0

Es scheint keine Arbeit, wenn ich Mock-Require, Fehler immer noch sagen, kann nicht Modul 'Aktionen/xxx' finden. – zhaozhiming

2

Ich denke, dass ich dieses Problem gelöst habe. Sie sollten 2 Paket verwenden: mock-require und proxyquire.

Vorausgesetzt Sie haben eine js-Datei wie folgt aussehen:

app.js

import action1 from 'actions/youractions'; 

export function foo() { console.log(action1()) }; 

Und Ihre Testcode sollte wie folgt schreiben:

app.test.js

import proxyquire from 'proxyquire'; 
import mockrequire from 'mock-require'; 

before(() => { 
    // mock the alias path, point to the actual path 
    mockrequire('actions/youractions', 'your/actual/action/path/from/your/test/file'); 
    // or mock with a function 
    mockrequire('actions/youractions', {actionMethod:() => {...})); 

let app; 
beforeEach(() => { 
    app = proxyquire('./app', {}); 
}); 

//test code 
describe('xxx',() => { 
    it('xxxx',() => { 
    ... 
    }); 
}); 

Dateien Baum

app.js 
    |- test 
    |- app.test.js 

Erster mock des Alias-Pfad durch Mock-erfordern in vor-Funktion und verspotten Ihr Testobjekt durch proxyquire in before Funktion.

14

Sie können auch ein babel Plugin verwende ich Autor: https://github.com/trayio/babel-plugin-webpack-alias Es wird Ihr aliased Weg in relative Pfade umwandeln nur durch ein babel-Plugin auf Ihre .babelrc einschließlich.

+0

Ich habe auf deinen Link geklickt und nach den dortigen Benutzerinformationen und deinen Benutzerinformationen beurteilt, es sieht so aus, als ob du der Autor des Plugins bist, also habe ich das entsprechend bearbeitet, weil es so ist ist gegen SO-Regeln, Software zu erwähnen, die Sie in einer Antwort erstellt haben * ohne * explizit zu sein, dass Sie es verfasst haben. (Dies gilt als Spam und führt zu hohen Strafen.) Wenn du irgendwie nicht der Autor bist, kannst du meine Bearbeitung rückgängig machen, aber vergewissere dich, dass die nächste Person, die auf den Link klickt, andernfalls die gleiche Schlussfolgerung macht wie ich. – Louis

+0

Auch diese Antwort, wie sie ist, ist Borderline-Link-only. Das Hinzufügen von Informationen zur Installation und Verwendung des Plugins würde dieses Problem beheben. – Louis

+4

Ich benutze das nicht in der Produktion, aber ich entwickle mich jetzt damit. Es scheint genau so zu sein wie erwartet. Ich bin ein Fan von Alias, und ich denke, mit einem Babel-Plugin, um dieses Problem zu lösen, ist der Weg zu gehen. Ich habe die Quelle oder irgendetwas nicht angeschaut, aber bis jetzt funktioniert das gut. –

3

Dannys Antwort ist großartig. Aber meine Situation ist ein bisschen anders. Ich benutzte Webpack resolve.alias, um alle Dateien unter src Ordner zu verwenden.

resolve: { 
    alias: { 
    '-': path.resolve(__dirname, '../src'), 
    }, 
}, 

und ein spezielles Präfix für meine eigene Module wie folgt verwenden:

import App from '-/components/App'; 

Um zu testen, Code wie dieser ich einen Befehl hinzufügen, um ln -sf src test/alias/- vor Mokka-Test verwenden, NODE_PATH=./test/alias Trick Danny aufmöbeln mit. So würde das endgültige Skript wie folgt sein:

{ 
    "scripts": { 
    "test": "ln -sf src test/alias/-; NODE_PATH=./test/alias mocha ./src/**/test/spec.js --compilers js:babel-core/register --recursive" 
    } 
} 

PS:

I verwendet - weil beautifal charactors wie @ oder ~ nicht sicher genug sind. Ich fand die Antwort für sichere Zeichen here

3

Ich stieß auch auf das gleiche Problem, aber mit diesem Plugin habe ich es gelöst.

https://www.npmjs.com/package/babel-plugin-webpack-aliases

Der Ausführungsbefehl Ihres „Mokka“ Lesen ist nicht die webpack.config.js, so dass es den Alias ​​nicht auflösen kann.
Berücksichtigen Sie bei der Erstellung dieses Plugins webpack.config.js beim Kompilieren mit "babel-core/register". Daher wird der Alias ​​auch während des Tests gültig sein.

npm i -D babel-plugin-webpack-aliases 

und fügen Sie diese Einstellung .babelrc

{ 
    "plugins": [ 
     [ "babel-plugin-webpack-aliases", { "config": "./webpack.config.js" } ] 
    ] 
}