2016-11-04 2 views
5

Я строю модуль node.js, и я также хочу проверить его с помощью Jasmine.Intercept EventEmitters with Jasmine

Пусть говорят мой модуль выглядеть примерно так:

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 
}; 

Как я могу проверить мой модуль с Jasmine нацеливания всех мои событий я испускаю?

Что-то вроде этого:

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(); 
    }); 
    }); 
}); 

ответ

0

я сделать это, используя proxyquire: https://github.com/thlorenz/proxyquire

В тестовом файле:

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'); 
    }); 
}); 

Вы также можете использовать шпиона в качестве притворной EventEmitter, и т.д. .

+0

Привет, спасибо за ваш ответ, могу ли я попросить более подробный пример? Я новичок в мире тестирования модулей, и было бы неплохо понять его лучше ... –

+0

Не уверен, что этот пример полностью работает, поскольку я только что написал его inline. Но вы должны прочитать это: http://jasmine.github.io/2.5/introduction И также документы на proxyquire. –

+0

Я проверю его, как только смогу, и дам вам знать. Спасибо –

0

Основная проблема заключается в том, что greet на самом деле не выставлен и поэтому недоступен в тестах. Вот несколько способов для этого:

  1. Добавьте его в цепочку прототипов, чтобы сделать его доступным (это то, что я сделал ниже).

  2. Открыть функцию в module.exports. Это можно было бы обернуть в process.env.NODE_ENV !== production, чтобы исключить его из производства.

  3. Не подвергайте его воздействию, а проверяйте функциональность излучателя события и влияние функции (это, вероятно, не идеально).

Чтобы достичь того, чего вы хотите, вы могли бы обезьяна патч функции и тест, что они были вызваны и проверить результат greet по отдельности:

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!"); 
    }); 
});