2016-01-03 14 views
28

Ho foo.js file:Come disattivare la funzione esportata in ES6?

export function bar (m) { 
    console.log(m); 
} 

e un altro file che utilizza foo.js, cap.js:

import { bar } from 'foo'; 

export default m => { 
    // Some logic that I need to test 
    bar(m); 
} 

ho test.js:

import cap from 'cap' 

describe('cap',() => { 
    it('should bar',() => { 
     cap('some'); 
    }); 
}); 

In qualche modo Ho bisogno di eseguire l'override dell'implementazione di bar(m) nel test. C'è un modo per fare questo?

P.S. Io uso babel, webpack e moka.

+0

in cui avete bisogno di sostituire in cap o il test? –

+0

Nel test, in realtà ho bisogno di questo per isolare la funzionalità cap dalla barra a scopo di test. –

+0

Quale versione di babele stai usando? –

risposta

32

Ouch .. Ho trovato la soluzione, quindi uso sinon per lo stub e import * as foo from 'foo' per ottenere l'oggetto con tutte le funzioni esportate in modo che possa stubli.

import sinon from 'sinon'; 
import cap from 'cap'; 
import * as foo from 'foo'; 

sinon.stub(foo, 'bar', m => { 
    console.log('confirm', m); 
}); 

describe('cap',() => { 
    it('should bar',() => { 
    cap('some'); 
    }); 
}); 
+5

Non penso che funzionerà in un ambiente ES6 (non-babel-transpiled) – Bergi

+9

@Bergi sì, in base alla mia attuale comprensione, l'export in realtà esporta oggetti immutabili, e poiché in questo momento è implementato utilizzando oggetti regolari potrebbe fallire in seguito . –

+0

Quindi quale sarà una soluzione a questo? –

3

È possibile sostituire/riscrivere/esportare stub solo dall'interno del modulo stesso. (Ecco un explanation)

Se si riscrive 'foo.js' in questo modo:

var bar = function bar (m) { 
    console.log(m); 
}; 

export {bar} 

export function stub($stub) { 
    bar = $stub; 
} 

È quindi possibile ignorare che nel vostro test come questo:

import cap from 'cap' 
import {stub} from 'foo' 

describe('cap',() => { 
    it('should bar',() => { 
     stub(() => console.log('stubbed')); 
     cap('some'); // will output 'stubbed' in the console instead of 'some' 
    }); 
}); 

Ho creato un Plugin Babel che trasforma automaticamente tutte le esportazioni in modo che possano essere stub: https://github.com/asapach/babel-plugin-rewire-exports

0

È possibile utilizzare babel-plugin-rewire (npm install --save-dev babel-plugin-rewire)

E poi nel test.js utilizzare la funzione __Rewire__ sul modulo importato di sostituire la funzione di quel modulo:

// test.js 
import sinon from 'sinon' 

import cap from 'cap' 

describe('cap',() => { 
    it('should bar',() => { 
    const barStub = sinon.stub().returns(42); 
    cap.__Rewire__('bar', barStub); // <-- Magic happens here 
    cap('some'); 
    expect(barStub.calledOnce).to.be.true; 
    }); 
}); 

Assicurarsi di aggiungere rewire ai tuoi plugin Babel in .babelrc:

// .babelrc 
{ 
    "presets": [ 
    "es2015" 
    ], 
    "plugins": [], 
    "env": { 
    "test": { 
     "plugins": [ 
     "rewire" 
     ] 
    } 
    } 
} 

Infine, come puoi vedere il plugin babel-plugin-rewire è abilitato solo nell'ambiente di test, quindi dovresti chiamare il runner di prova con il set di variabili di ambiente BABEL_ENV a test (che probabilmente stai facendo già):

env BABEL_ENV=test mocha --compilers js:babel-core/register test-example.js 

Nota: non ho potuto ottenere babel-plugin-rewire-exports al lavoro.

0

Mentre la soluzione @Mike funzionava con le vecchie versioni di sinon, è stata rimossa sinon 3.0.0.

Ora, invece di:

sinon.stub(obj, "meth", fn); 

si dovrebbe fare:

stub(obj, 'meth').callsFake(fn) 

Esempio di scherno google OAuth api:

import google from 'googleapis'; 

const oauth2Stub = sinon.stub(); 

sinon.stub(google, 'oauth2').callsFake(oauth2Stub); 

oauth2Stub.withArgs('v2').returns({ 
    tokeninfo: (accessToken, params, callback) => { 
     callback(null, { email: '[email protected]' }); // callback with expected result 
    } 
}); 
Problemi correlati