2017-03-02 3 views
5

J'ai une classe AProvider qui nécessite './b.provider'.Proxyquire ne cogne pas ma classe requise

const BProvider = require('./b.provider'); 

class AProvider { 
    static get defaultPath() { 
    return `defaults/a/${BProvider.getThing()}`; 
    } 
} 

module.exports = AProvider; 

b.provider.js est adjacent à a.provider.js et ressemble

global.stuff.whatever = require('../models').get('Whatever'); // I didn't write this! 

class BProvider { 
    static getThing() { 
    return 'some-computed-thing'; 
    } 
} 
module.exports = BProvider; 

Dans mon test, je l'utilise proxyquire pour se moquer des ./b.provider comme suit:

import { expect } from 'chai'; 
import proxyquire from 'proxyquire'; 

describe('A Provider',() => { 
    const Provider = proxyquire('../src/a.provider', { 
    './b.provider': { 
     getThing:() => 'b-thing' 
    }, 
    }); 

    describe('defaultPath',() => { 
    it('has the expected value',() => { 
     expect(Provider.defaultPath).to.equal('defaults/a/b-thing') 
    }); 
    }); 
}); 

Cependant quand je lance le test BProvider est nécessitant toujours le './b.provider' réelle pas le talon et la référence de BProvider à global.stuff.whatever renvoie une erreur.

Pourquoi cela ne fonctionne-t-il pas?

+1

Avez-vous essayé de déclarer la directive proxyquire dans une instruction 'before '? En outre, je ne sais pas si cela pourrait aider, mais cet article semble penser que l'utilisation de sinon à côté est nécessaire: http://www.thoughtdelimited.org/thoughts/post.cfm/instructing-proxyquire-to-ignore-nested-requires –

+0

Lien intéressant. Je ne me suis pas rendu compte que le Require était encore arrivé malgré proxyquire. Dans un taxi en ce moment mais testera une solution quand je rentre à la maison. Merci. –

+0

Okay J'ai résolu le problème et j'ai trouvé une solution facile que je publierai ci-dessous. Merci @ francisco.preller pour m'avoir indiqué dans la bonne direction. –

Répondre

4

La réponse à pourquoi cela se produit est comme suit

proxyquire exige toujours le code sous-jacent avant stubbing dehors. Cela permet d'activer les appels.

La solution est simplement de explicitement interdire appels.

Le test devient:

import { expect } from 'chai'; 
import proxyquire from 'proxyquire'; 

describe('A Provider',() => { 
    const Provider = proxyquire('../src/a.provider', { 
    './b.provider': { 
     getThing:() => 'b-thing', 
     '@noCallThru': true 
    }, 
    }); 

    describe('defaultPath',() => { 
    it('has the expected value',() => { 
     expect(Provider.defaultPath).to.equal('defaults/a/b-thing') 
    }); 
    }); 
}); 

exécution de ce test fonctionne parfaitement.