Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
218 views
in Technique[技术] by (71.8m points)

javascript - EventEmitter unit test using mocha and sinon doesn't work

The part of my codes "expect(spy.called).to.be.true" is supposed to be true. but the test result shows something like this.

  AssertionError: expected false to be true
  + expected - actual

  -false
  +true

I tried to do an unit test of EventEmitter with mocha. Soon, I realized that I needed to check the listener function is called. So I imported sinon module. But anything I expected didn't happen to me. My codes are as follows. Please let me know what is wrong with my codes. thanks a lot in advance.

<test.js>

const findPattern = require('./findPatterns');
const expect = require('chai').expect;
const sinon = require('sinon');
const FakeTimers = require('@sinonjs/fake-timers');

describe('findPattern', function() {

  const sampleFiles = ['./sample/sample1.txt', './sample/sample2.txt', './sample/sample3.txt'];
  const regEx = /[0-9]+/g;

  it('findPattern', function() {
    const clock = FakeTimers.createClock();

    const o = {
      f: (file) => console.log('Read from ' + file)
    };

    const spy = sinon.spy(o, "f");

    findPattern(sampleFiles, regEx)
      .on('error', (err) => console.log('error: ' + err))
      .on('read', spy)
      .on('found', (file, match) => console.log('Matched ' + match + ' in file' + file));

    clock.setTimeout(function() {
      expect(spy.called).to.be.true;
    }, 1000);

    clock.tick(1000);
  });
});

<findPatterns.js>

const EventEmitter = require('events');
const fs = require('fs');

function findPattern(files, regex) {
  const emitter = new EventEmitter();

  files.forEach(function(file) {
    fs.readFile(file, "utf-8", (err, content) => {
      if (err) {
        return emitter.emit('error', err);
      }

      emitter.emit('read', file);

      const matches = content.match(regex);
      if (matches) {
        matches.forEach(i => {
          emitter.emit('found', file, i);
        });
      }
    }); 
  });

  return emitter;
}

module.exports = findPattern;
question from:https://stackoverflow.com/questions/65845742/eventemitter-unit-test-using-mocha-and-sinon-doesnt-work

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

Well, I think I found out a kind of solution. I guess the problem was something about asynchronous issue. The "expect function" seemed to called before finishing read files. So I changed my code and get the result I expected. By the way timer function seems that it doesn't work properly. Please review my changed code and give some advice if I did something wrong.

const findPattern = require('./findPatterns');
const expect = require('chai').expect;
const sinon = require('sinon');

describe('findPattern', function() {
  const sampleFiles = ['./sample/sample1.txt', './sample/sample2.txt', './sample/sample3.txt'];
  const regEx = /[0-9]+/g;
  
  const readFun = (file) => console.log('Read from ' + file);
  const o = {
    f: readFun
  };

  const spy = sinon.spy(o, "f");

  beforeEach(function(done) {
    findPattern(sampleFiles, regEx, done)
      .on('error', (err) => console.log('error: ' + err))
      .on('read', spy)
      .on('found', (file, match) => console.log('Matched ' + match + ' in file' + file));
  });

  it('findPattern', function() {
    expect(spy.called).to.be.true;
  });
});
const EventEmitter = require('events');
const fs = require('fs');

function readFile(file, regex, emitter, callback) {
  fs.readFile(file, "utf-8", (err, content) => {
    if (err) {
      return emitter.emit('error', err);
    }
    
    emitter.emit('read', file);
    
    const matches = content.match(regex);
    if (matches) {
      matches.forEach(i => {
        emitter.emit('found', file, i);
      });
    }

    callback();
  }); 
}

function findPattern(files, regex, done) {
  const emitter = new EventEmitter();

  let completed = 0;

  function finish() {
    if (++completed == files.length) {
      return done();
    } 
  }

  files.forEach(function(file) {
    readFile(file, regex, emitter, finish);
  });

  return emitter;
}

module.exports = findPattern;

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...