2013-12-23 5 views
6

Ich habe ein großes Problem mit meinen Mokka-Tests um ein globales Objekt, das ich benutze. Ich bin in der Lage, das folgende MRE zu erzeugen, das nicht den exakt gleichen Fehler liefert, sondern das problematische (Buggy?) Verhalten veranschaulicht. Jede Einsicht würde sehr geschätzt werden.Mokka Global Scoping Issues

Ich habe folgende main.js Datei in /lib:

exports.exec = function(){ 
    console.log(test); 
} 

Dann wurde die folgende in /test/test.js:

var should = require('should'); 
var main = require('../lib/main'); 

global.test = {something: 1}; 

describe('normal test', function(){ 
    beforeEach(function(){ 
    global.test = {another: 2}; 
    }), 

    afterEach(function(){ 
    delete global.test; 
    }); 

    it ('might work with global', function(){ 
    main.exec(); 
    }) 
}); 

Schließlich ist dies test/test2.js:

var should = require('should'); 
var main = require('../lib/main'); 

global.test = {third: 3}; 

describe('some test', function(){ 
    it ('messes up global', function(){ 
    main.exec(); 
    }) 
}); 

Ich gehe davon aus, dass die Der erste Test würde 01 ausgebenund die zweite würde {third: 3} drucken. In der Tat ist dies das Verhalten, das ich erhalte, wenn ich jeden Test unabhängig voneinander abspiele. z.B.

[email protected]:~/workspace/mocha-test$ mocha test/test2.js 

    { third: 3 } 
․ 

    1 passing (6ms) 

jedoch beim Laufen sowohl Tests mit npm Paketen should und mocha (1.16.1), erhalte ich die folgende Ausgabe:

[email protected]:~/workspace/mocha-test$ mocha 

    { another: 2 } 
․․ 

    1 passing (6ms) 
    1 failing 

    1) some test messes up global: 
    ReferenceError: test is not defined 
     at Object.exports.exec (/home/jeff/workspace/mocha-test/lib/main.js:3:15) 
     at Context.<anonymous> (/home/jeff/workspace/mocha-test/test/test2.js:8:10) 
     at Test.Runnable.run (/usr/lib/node_modules/mocha/lib/runnable.js:211:32) 
     at Runner.runTest (/usr/lib/node_modules/mocha/lib/runner.js:355:10) 
     at /usr/lib/node_modules/mocha/lib/runner.js:401:12 
     at next (/usr/lib/node_modules/mocha/lib/runner.js:281:14) 
     at /usr/lib/node_modules/mocha/lib/runner.js:290:7 
     at next (/usr/lib/node_modules/mocha/lib/runner.js:234:23) 
     at Object._onImmediate (/usr/lib/node_modules/mocha/lib/runner.js:258:5) 
     at processImmediate [as _immediateCallback] (timers.js:330:15) 
+0

Je mehr ich es ansehe, desto zuversichtlicher bin ich, dass dies unerwünschtes Verhalten ist; hier ein Problem melden: https://github.com/visionmedia/mocha/issues/1083 –

+1

Ich habe dieses Problem schon vorher gesehen - ich denke, es ist am besten, eine kleine kleine make-Datei zu erstellen, die jeden Test unabhängig mit einer einfachen for-Schleife ausführt . –

+0

Ihr Problem wird wahrscheinlich geschlossen sein - ich denke, es gab ein Problem, das etwas ähnliches hatte. Der Benutzer wollte, dass der erforderliche Cache gelöscht wird. https://github.com/visionmedia/mocha/issues/536 –

Antwort

9

test2.js soll wie folgt strukturiert sein:

describe('some test', function(){ 
    before(function(){ 
    global.test = {third: 3}; 
    }); 

    it ('messes up global', function(){ 
    main.exec(); 
    }) 
}); 

Travisjeffery auf der GitHub Problem im Kommentar erwähnt erläutert:

mocha lädt die Dateien und führt dann die Suites aus, um Ihre Tests zuverlässig einzurichten, sollte das Setup innerhalb der Suite sein.

Wie @SB hervorhebt, ist dies möglicherweise nicht dafür geeignet, Dinge wie globale Variablen in Tests zu teilen.

+0

Ein Test-Runner-Framework ruft wiederholt Pre-Test-After auf. Der globale Status wird am Anfang initialisiert, nicht irgendwie verpackt und in jedem Test erledigt. Wenn der globale Zustand als eine Nebenwirkung des Tests modifiziert wird, werden diese Nebenwirkungen in nachfolgenden Tests gesehen. –

+0

Das ist ein großartiger Punkt, ich habe meine Tests in einen anderen Bereich getrennt und es funktioniert jetzt. Vielen Dank! –

+0

Normalerweise benötigen wir einige Pakete vor der Testklasse. Wenn dies in einer globalen Variablen erforderlich ist, wird diese Lösung Ihr Problem nicht beheben. –