3

ジャスミンを使用したファイル アクセスのテストに問題があります。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'

そして最後のものは私に奇妙な '([Object] does not have a method emit)' を与えますが、これは間違っています。

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')

this2 番目の問題については、関数呼び出しをクロージャーでラップしただけで機能しましたが、テストを実行するときにコンテキストが完全にめちゃくちゃになる理由を本当に理解する必要があります。

4

2 に答える 2

2

この質問を参照してください

私はあなたがする必要があると思います:

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

これは、テスト定義時間ではなく、実際のテスト実行中に期待マッチャーが呼び出すことができる無名関数を定義します。

toHaveBeenCalled2番目の問題では、任意の関数ではなく、ジャスミンスパイオブジェクトのみを呼び出すことができます。関数をラップするだけで

spyOn(watcher, 'emit').andCallThrough()

Spy.andCallThrough()のjasmineAPIドキュメントを参照してください

于 2011-08-07T04:41:36.103 に答える