Hi,
I'm trying to create a test involving EventEmitters and Sinon.
Test1 below shows the working version with Mocha and Chai. I'm sure there must be a way to do this more elegantly with Sinon, although my attempts (Tests 2-4) so far have proved otherwise.
I'm lead to believe that perhaps there is something fundamentally wrong with my understanding of Sinon or it can't be done. I'm guessing it's the former.
Anyone able to point out where I took a wrong turn?
Thanks
/* eslint-env mocha */
'use strict'
const fs = require('fs-extra')
const path = require('path')
const EventEmitter = require('events')
const chai = require('chai')
const chaiAsPromised = require('chai-as-promised')
chai.use(chaiAsPromised)
const assert = chai.assert
const expect = chai.expect
chai.should()
const Q = require('q')
const sinon = require('sinon')
describe('Tests', function () {
describe('asyncTesting', function () {
function listFiles (directory, eventNotifier) {
// Use the fs-events interface without promises
fs.readdir(directory, 'utf8', (error, files) => {
if (error) {
console.log('error occured', error)
throw error
}
eventNotifier.emit('completed', files)
})
}
it('Test1: correctly lists files (without promises or sinon)', function (done) {
// The directory C:\Temp\files contains the files file1.txt, file2.txt
// and file3.txt
let currentDirectory = path.normalize('C:\\Temp\\files')
let expectedFiles = ['file1.txt', 'file2.txt', 'file3.txt']
let listEvent = new EventEmitter()
listEvent.on('completed', function (files) {
files.forEach((testFile) => {
let errorMessage = testFile + ' is not expected'
assert.isTrue(expectedFiles.includes(testFile), errorMessage)
})
done()
})
listFiles(currentDirectory, listEvent)
})
async function listFilesAsync (directory, eventNotifier) {
// Use the fs-events interface without promises but
// force waiting until we are finished
// console.log(eventNotifier)
fs.readdir(directory, 'utf8', (error, files) => {
if (error) {
console.log('error occured', error)
throw error
}
eventNotifier.emit('completed', files)
// console.log('fired completed event')
})
}
it('Test2: confirm emit was called on event', async function () {
let currentDirectory = path.normalize('C:\\Temp\\files')
let listEvent = new EventEmitter()
// Makes no difference if we register the 'completed'
// event on listEvent or not
// listEvent.on('completed', (files) => {
// console.log('called completed' + files)
// })
// Try catch the emit
let emitEventSpy = sinon.spy(listEvent, 'emit')
await listFilesAsync(currentDirectory, emitEventSpy)
emitEventSpy.restore()
// Always fails
return expect(emitEventSpy.calledOnce).to.equal(true)
})
it('Test3: correctly calls emit (with sinon but without promises)', async function () {
// The directory C:\Temp\files contains the files file1.txt, file2.txt
// and file3.txt
let currentDirectory = path.normalize('C:\\Temp\\files')
// let expectedFiles = ['file1.txt', 'file2.txt', 'file3.txt']
let listEvent = new EventEmitter()
// Replace the original method 'emit' with magical sinon one
let eventSpy = sinon.spy(listEvent, 'emit')
// let eventSpy = sinon.spy(listEvent, 'on')
await listFilesAsync(currentDirectory, eventSpy)
eventSpy.restore()
// eventSpy is never called with 'emit'
sinon.assert.called(eventSpy)
// Would like to test returned readFiles, but this never happens
// sinon.assert.calledWith(eventSpy, 'completed', expectedFiles)
})
it('Test4: following mocha spies test', async function () {
let currentDirectory = path.normalize('C:\\Temp\\files')
// let expectedFiles = ['file1.txt', 'file2.txt', 'file3.txt']
let listEvent = new EventEmitter()
let emitEventSpy = sinon.spy()
listEvent.on('completed', emitEventSpy)
await listFilesAsync(currentDirectory, listEvent)
// Always fails
sinon.assert.calledOnce(emitEventSpy)
})
})
})