使用jasmine和node.js模拟文件系统

时间:2011-08-07 00:57:05

标签: node.js mocking jasmine fs

我在使用jasmine测试文件访问时遇到问题。我正在编写一个简单的观察程序,它使用require('fs').watch注册一个回调并发出一个包含文件名的事件,这里没什么特别的。

然而,当我尝试编写模拟fs模块的测试时,我遇到了几个问题。

这是我的Watcher课程(CoffeeScript领先)

class Watcher extends EventEmitter
  constructor: ->
    @files = []

  watch: (filename) ->
    if !path.existsSync filename 
      throw "File does not exist."
    @files.push(filename)
    fs.watchFile filename, (current, previous) ->
      this.emit('file_changed')

以下是我的测试:

it 'should check if the file exists', ->
  spyOn(path, 'existsSync').andReturn(true)
  watcher.watch 'existing_file.js'
  expect(path.existsSync).toHaveBeenCalledWith 'existing_file.js'

这个很好用并且没有任何问题,但是这个完全失败了,我不确定我是否正确传递了这些参数。

it 'should throw an exception if file doesn\'t exists', ->
  spyOn(path, 'existsSync').andReturn(false)
  expect(watcher.watch, 'undefined_file.js').toThrow()
  expect(path.existsSync).toHaveBeenCalledWith 'undefined_file.js'

最后一个给了我奇怪的'([对象]没有方法发射)'这是错误的。

it 'should emit an event when a file changes', ->
  spyOn(fs, 'watchFile').andCallFake (file, callback) ->
    setTimeout( ->
      callback {mtime: 10}, {mtime: 5}
    , 100)
  spyOn(path, 'existsSync').andReturn(true)
  watcher.watch 'existing_file.js'
  waits 500
  expect(watcher.emit).toHaveBeenCalledWith('file_changed')

对于第二个问题,我只是将一个函数调用包装在一个闭包中,但是我确实需要理解为什么在运行我的测试时,this上下文完全搞砸了。

2 个答案:

答案 0 :(得分:2)

请参阅this question

我认为你需要这样做:

expect(-> watcher.watch 'undefined_file.js').toThrow 'File does not exist.'

它定义了期望匹配器在实际测试运行期间可以调用的匿名函数,而不是在测试定义时间期间。

对于第二个问题,您只能在茉莉花间谍对象上调用toHaveBeenCalled,而不是任意函数。您可以通过执行

来包装该函数
spyOn(watcher, 'emit').andCallThrough()

请参阅the jasmine API docs on Spy.andCallThrough()

答案 1 :(得分:0)

您可以使用memfs进行文件系统模拟。