2015-09-13 7 views
20

Ich mag würde zu Einheit der folgenden ES6 Klasse testen:Mocking JavaScript-Konstruktor mit Sinon.JS

// service.js 
const InternalService = require('internal-service'); 

class Service { 
    constructor(args) { 
    this.internalService = new InternalService(args); 
    } 

    getData(args) { 
    let events = this.internalService.getEvents(args); 
    let data = getDataFromEvents(events); 
    return data; 
    } 
} 

function getDataFromEvents(events) {...} 

module.exports = Service; 

Wie kann ich verspotten Konstruktor mit Sinon.JS um getEvents von internalService zu verspotten getData zu testen?

Ich schaute auf Javascript: Mocking Constructor using Sinon, war aber nicht in der Lage, eine Lösung zu extrahieren.

// test.js 
const chai = require('chai'); 
const sinon = require('sinon'); 
const should = chai.should(); 

let Service = require('service'); 

describe('Service', function() { 
    it('getData', function() { 
    // throws: TypeError: Attempted to wrap undefined property Service as function 
    sinon.stub(Service, 'Service').returns(0); 
    }); 
}); 
+0

Werfen Sie einen Blick auf diese Frage: [Javascript: Mocking Constructor mit Sinon] (https://stackoverflow.com/questions/14569499/javascript-mocking-constructor-using-sinon). – sdgluck

+0

@sdgluck Ich tat, aber ich war nicht in der Lage, die Lösung für meinen Fall zu extrahieren – krl

+0

Mögliches Duplikat von [Javascript: Mocking Constructor mit Sinon] (https://stackoverflow.com/questions/14569499/javascript-mocking-constructor- using-sinon) –

Antwort

17

können Sie entweder einen Namespace erstellen oder eine Stub-Instanz erstellen sinon.createStubInstance verwenden (dies wird den Konstruktor nicht aufrufen).

Erstellen eines Namespace:

const namespace = { 
    Service: require('./service') 
}; 

describe('Service', function() { 
    it('getData', function() { 
    sinon.stub(namespace, 'Service').returns(0); 
    console.log(new namespace.Service()); // Service {} 
    }); 
}); 

eine Stub-Instanz erstellen:

let Service = require('./service'); 

describe('Service', function() { 
    it('getData', function() { 
    let stub = sinon.createStubInstance(Service); 
    console.log(stub); // Service {} 
    }); 
}); 
+0

danke! und wie füge ich eine Kopie von 'this.internalService.getEvents' hinzu, die eine Zeichenkette zurückgibt? – krl

+0

In dieser Antwort wird 'stub' jede Methode von' internalService' als 'sinon.stub' haben. So können Sie dies tun: 'stub.getEvents.returns (" einige Zeichenfolge ")' – sdgluck

+1

@sdgluck Ich fand es heraus. Dies ist, was ich brauchte 'let stub = sinon.createStubInstance (Service); stub.internalService = {getDataFromEvents: function() {return 'test'; }}; expect (stub.getData()) .toqual (...); ' – krl

1

Seit sinon.createStubInstance hat nach neuesten Versionen von Sinon entfernt worden ist, würde ich vorschlagen, einzelne Instanzmethoden Anstoßen auf der Prototyp, um den gewünschten Effekt zu erzielen. Etwas wie folgt aus:

const spy = sinon.stub(InternalService.prototype, 'getEvents').returns([{ id: 1 }]); 
const internalService = new InternalService(); 
console.log(internalService.getEvents()); 
// => [{ id: 1 }] 
+0

'createStubInstance' wurde nicht aus sinon entfernt: [sinon.createStubInstance-Deklaration] (https://github.com/sinonjs/sinon/blob/master/lib/sinon/stub.js#L63) –