mercredi 26 juillet 2017

Expect fs.watch callback to be called in Jasmine

I have a class that accepts a callback in it's constructor. It also has a method loadFile that gets the content from the file, modifies it a bit and calls the callback with the modified content. Up to this point a class can be easily tested.

Now, I want to add a watch feature. loadFile will do what I just described and will start watching a file. Every time the file changes, the process will be repeated (load the file -> modify the content -> call the callback). I try to test it using Jasmine but I cannot make it work.

The simplified code looks like this:

const path = require('path')
const watch = require('fs').watch
const write = require('fs').writeFile

class Loader {
  constructor (callback) {
    this.callback = callback
  }

  loadFile (file) {
    watch(file, (p, e) => {
      console.log('path changed', p, e)
      // do some important stuff here
      this.callback(p)
    })
  }
}

describe ('Loader', () => {
  var loader
  var callback

  beforeEach(() => {
    callback = jasmine.createSpy('callback')
    loader = new Loader(callback)
  })

  it('converts a markdown file', () => {
    // this file already exists
    const file = path.join(__dirname, 'md', 'header.md')

    loader.loadFile(file)
    write(file, 'hello', 'utf8')
    expect(callback).toHaveBeenCalled()
    console.log('end of test')
  })
})

The command line result is:

Started
end of test
path changed change header.md
path changed change header.md
F

Failures:
1) Loader converts a markdown file
  Message:
    Expected spy callback to have been called.
  Stack:
    Error: Expected spy callback to have been called.
        at Object.it (/path/to/spec/callback.spec.js:34:22)

1 spec, 1 failure
Finished in 0.015 seconds

This test does not load actual content, I simplified it to show the problem I encountered: the callback is called, but after the expectation.

I've spent a lot of time figuring out what is wrong but I failed. I think I've tried every possible combinations of using done() that Jasmine provides, but I didn't have any luck. I would appreciate any help with this.

Aucun commentaire:

Enregistrer un commentaire