使用Jasmine拦截EventEmitters

时间:2016-11-04 13:57:16

标签: javascript jasmine

我正在构建一个node.js模块,我也希望用Jasmine进行测试。

假设我的模块看起来与此类似:

@Controller
public class SinglePageAppController {
    @RequestMapping(value = {"/", "/users/**", "/campaigns/**"})
    public String index() {
        return "index";
    }
}

如何使用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
};

2 个答案:

答案 0 :(得分: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等。

答案 1 :(得分:0)

主要问题是greet并未真正暴露,因此无法在测试中访问。以下是处理此问题的一些方法:

  1. 将其添加到原型链中以使其可访问(这是我在下面所做的)。

  2. module.exports中公开该功能。这可以包含在process.env.NODE_ENV !== production中以将其从生产中排除。

  3. 不公开它,但测试事件发射器功能和功能的影响(这可能不太理想)。

  4. 为了实现你想要的,你可以修补函数并测试它们被调用并单独测试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!");
      });
    });