2016-11-04 2 views
5

Ich baue ein node.js Modul und ich möchte es auch mit Jasmine testen.Intercept EventEmitter mit Jasmine

Lassen Sie sagen, mein Modul so aussehen:

var myModule = function (foo, bar) { 

    // Begin a workflow 
    var workflow = new (require('events').EventEmitter)(); 

    workflow.on('test', function() { 
    var greet = greet(); 
    return greet; 
    }); 

    workflow.emit('test'); 

}; 

function greet() { 
    return "Hi!"; 
} 

module.exports = { 
    myModule: myModule 
}; 

Wie kann ich mein Modul testen mit Jasmine ich emittieren alle meine Veranstaltungen Targeting?

Etwas wie folgt aus:

var myModule = require('../myModule.js');  

describe('My Module test', function() { 

    it('should get greet value', function() { 
    myModule.on('test', function() { // "test" as I wrote in myModule 
     expect(myModule.greet).toHaveBeenCalled(); 
    }); 
    }); 
}); 

Antwort

0

ich dies mit proxyquire erreichen: https://github.com/thlorenz/proxyquire

In Ihrem Testdatei:

var proxyquire = require('proxyquire'); 
var mockEvents = {}; 
var myModule = proxyquire('../myModule.js', { 
    events: mockEvents 
}); 

describe('My Module test', function() { 
    beforeEach(function() { 
    mockEvents.EventEmitter = function() {}; 

    mockEvents.EventEmitter.prototype = { 
     on: function() { }, 
     emit: function() { } 
    }; 

    spyOn(mockEvents.EventEmitter.prototype, 'on'); 
    spyOn(mockEvents.EventEmitter.prototype, 'emit'); 
    }); 

    it('should get greet value', function() { 
    myModule() 
    expect(mockEvents.EventEmitter.prototype.on).toHaveBeenCalledWith('test'); 
    expect(mockEvents.EventEmitter.prototype.emit).toHaveBeenCalledWith('test'); 
    }); 
}); 

Sie auch einen Spion als Mock EventEmitter verwenden können, usw. .

+0

Hallo, danke für deine Antwort, kann ich ein ausführlicheres Beispiel verlangen? Ich bin neu in der Unit-Test-Welt und es wäre schön, es besser zu verstehen ... –

+0

Nicht sicher, ob dieses Beispiel vollständig funktioniert, wie ich es gerade inline geschrieben habe. Aber Sie sollten dies lesen: http://jasmine.github.io/2.5/introduction Und auch die Dokumente auf Proxyquire. –

+0

Ich werde es so schnell wie möglich testen und Ihnen mitteilen. Danke –

0

Das Hauptproblem ist, dass greet ist nicht wirklich exponiert und daher in den Tests nicht zugänglich. Hier sind einige Möglichkeiten, dies zu umgehen:

  1. ihn jetzt an der Prototypkette zu zugänglich zu machen (das ist, was ich unten getan).

  2. Setzen Sie die Funktion in module.exports frei. Dies könnte in eine process.env.NODE_ENV !== production verpackt werden, um es von der Produktion auszuschließen.

  3. Nicht belichten, sondern die Ereignisemitterfunktionalität und Auswirkung der Funktion testen (dies ist wahrscheinlich nicht ideal).

Um das zu erreichen, was Sie wollen, könnten Sie die Funktionen und Testaffen patchen, dass sie das Ergebnis der greet einzeln aufgerufen wurden und testen:

MyModule.js

var EventEmitter = require('events').EventEmitter; 
var MyModule = function (foo, bar) { 
    // Begin a workflow 
    var workflow = new EventEmitter(); 

    workflow.on('test', function() { 
    return this.greet(); 
    }.bind(this)); 

    workflow.emit('test'); 
}; 

MyModule.prototype.greet = function() { 
    return "Hi!"; 
}; 

module.exports = MyModule; 

MyModule-tests.js

var EventEmitter = require('events').EventEmitter; 

describe('MyModule', function() { 
    it('emits an event upon construction', function() { 
    // Monkey patch 
    var originalEventEmitterOn = EventEmitter.prototype.on; 
    EventEmitter.prototype.on = jasmine.createSpy('on'); 

    // Create module 
    var MyModule = require('./MyModule'); 
    new MyModule(); 
    expect(EventEmitter.prototype.on).toHaveBeenCalled(); 

    // Reset 
    EventEmitter.prototype.on = originalEventEmitterOn; 
    }); 

    it('calls greet upon construction', function() { 
    var MyModule = require('./MyModule'); 

    // Monkey patch 
    var originalGreet = MyModule.prototype.greet 
    MyModule.prototype.greet = jasmine.createSpy('greet'); 

    var myModule = new MyModule(); 
    expect(myModule.greet).toHaveBeenCalled(); 

    // Reset 
    MyModule.prototype.greet = originalGreet; 
    }); 

    it('returns "Hi!"', function() { 
    var MyModule = require('./MyModule'); 
    var myModule = new MyModule(); 
    expect(myModule.greet()).toBe("Hi!"); 
    }); 
});