簡體   English   中英

存根ES6 EventEmitter類函數

[英]Stub a ES6 EventEmitter class function

我有一個擴展EventEmitter的依賴項類,我需要測試使用此依賴項的函數如何根據觸發的事件做出反應。 如何對EventEmitter類的函數進行存根?

依賴類

const EventEmitter = require('events');

class FooBar extends EventEmitter {

  constructor() {
    super();

    this.doingSomething = false;
  }

  doSomething() {
    if (this.doingSomething === false) {
      this.doingSomething = true;
      this.emit('startedDoingSomething');
    }
    else {
      this.emit('alreadyDoingSomething');
    }
  }
}

module.exports = FooBar;

被測模塊

let Foobar = require('FooBar');
let fooBar = new FooBar();

exports.myFunction = () => {
  // Set up listeners
  fooBar.once('startedDoingSomething', () => {
    fooBar.removeAllListeners();
    // Some functionality
    console.log('Started Doing Something');
  });

  fooBar.once('alreadyDoingSomething', () => {
    fooBar.removeAllListeners();
    // Some functionality
    console.log('Already Doing Something');
  });

  // Call the event-emitting function
  fooBar.doSomething();
};

// Other functions that use fooBar

我正在使用Sinon來創建存根,但是我無法對有效發出事件的類函數進行存根。 我根據[Feature request]存根發出的內容對測試進行了建模,但是由於被存根的事件發射器依賴項是一個類,因此不得不進行一些修改。

測試

let chai = require('chai');
let sinon = require('sinon');
let FooBar = require('FooBar');
let dependentModule = require('./dependentModule');

describe('Dependent Module', () => {
  it('alreadyDoingSomething', () => {
    sinon.stub(FooBar.prototype, 'pause', () => {
      FooBar.prototype.emit('alreadyDoingSomething');
    });

    // Assertion statements here
    expect(dependentModule.myFunction()).to...
  });
});

即使正在調用存根函數,該方法實際上也不會發出事件。

測試中的第13行,它調用dependentModule.myFunction()

然后它跳到被測從屬模塊的第5行

然后在受測從屬模塊的第19行中,它調用fooBar.doSomething()

然后跳到Dependency Class中的第12行,那里this.doingSomething為false,因此它發出了startedDoingSomething

然后,它跳到“受測模塊”中的第7行,它調用fooBar.removeAllListeners(); ,這意味着在同一文件的第34行注冊的事件處理程序也將被刪除。

這是真的嗎?

現在,假設第7行“受測模塊”中的fooBar.removeAllListeners已被注釋掉。

然后在Test的第13行之后,它調用FooBar.prototype.pause ,然后依次調用FooBar.prototype.emit('alreadyDoingSomething');

問題在於,當FooBar.prototype.emit時, this在上下文中不等於在受測模塊中的第2行中聲明的fooBar (等於FooBar.prototype

所以FooBar.prototype.emit('alreadyDoingSomething'); 不會觸發在受測模塊中第12行中定義的事件處理程序。

我們將需要找到一種方法來調用fooBar.emit('alreadyDoingSomething')

但這是不可能的,因為除非使用諸如rewire之類的庫,否則永遠不會導出fooBar

現在假設我們添加了exports.fooBar = fooBar; 到被測相關模塊的末尾。

並且我們還將Test中的第9行更改為this.emit('alreadyDoingSomething')這很重要,因為我們需要在調用this.emit('alreadyDoingSomething')時需要上下文作為實例,在我們的例子中是fooBar

現在在測試中,當調用dependentModule.fooBar.pause()時,將觸發一個“已經開始做事”。

現在,您應該在控制台中看到Already Doing Something

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM