2012-01-26 12 views
12

私は予想通り、次の機能が実行することをテストしたいと思います。ここではmochaでキャッチされていないエラーをテストするにはどうすればよいですか?

function throwNextTick(error) { 
    process.nextTick(function() { 
     throw error; 
    }); 
} 

は私の試みです:

describe("throwNextTick", function() { 
    it("works as expected", function (next) { 
     var error = new Error("boo!"); 
     var recordedError = null; 
     process.once("uncaughtException", function (error) { 
      recordedError = error; 
     }); 

     throwNextTick(error); 

     process.nextTick(function() { 
      recordedError.should.be(error); 
      next(); 
     }); 
    }); 
}); 

しかし、モカは、それ自体にすべてのエラーを維持したい、と私のテストに失敗しているようですそれを取得したとき:

C:\Users\ddenicola\Programming (Synced)\pubit>mocha test/basicTest.js 

    throwNextTick 
    0) works as expected 

    ? 1 of 1 tests failed: 

    1) throwNextTick works as expected: 
    Error: boo! 
     at Test.fn (C:\Users\ddenicola\Programming (Synced)\pubit\test\basicTest.js:11:21) 
     at Test.run (C:\Users\ddenicola\AppData\Roaming\npm\node_modules\mocha\lib\runnable.js:144:15) 
     at Runner.runTest (C:\Users\ddenicola\AppData\Roaming\npm\node_modules\mocha\lib\runner.js:271:10) 
     at C:\Users\ddenicola\AppData\Roaming\npm\node_modules\mocha\lib\runner.js:315:12 
     at next (C:\Users\ddenicola\AppData\Roaming\npm\node_modules\mocha\lib\runner.js:199:14) 
     at C:\Users\ddenicola\AppData\Roaming\npm\node_modules\mocha\lib\runner.js:208:7 
     at next (C:\Users\ddenicola\AppData\Roaming\npm\node_modules\mocha\lib\runner.js:157:23) 
     at Array.0 (C:\Users\ddenicola\AppData\Roaming\npm\node_modules\mocha\lib\runner.js:176:5) 
     at EventEmitter._tickCallback (node.js:192:40) 

アイデアがありますか?

答えて

27

アップデート:以下のコメントでケーシー・フォスターの礼儀:

あなたははるかに簡潔にこれを行うにはprocess.prependOnceListener('uncaughtException', ...)を使用することができますノード5月v6.0.0の通り。


旧答:process.listeners( 'uncaughtException')で

秘密の嘘:

http://nodejs.org/docs/latest/api/events.html#emitter.listeners

単にモカリスナーを削除し、独自のものを追加し、その後、再接続モカリスナー

は、以下を参照してください。

var assert = require('assert') 

function throwNextTick(error) { 
    process.nextTick(function() { 
     throw error 
    }) 
} 


describe("throwNextTick", function() { 
    it("works as expected", function (next) { 
     var error = new Error("boo!") 
     var recordedError = null 
     var originalException = process.listeners('uncaughtException').pop() 
     //Needed in node 0.10.5+ 
     process.removeListener('uncaughtException', originalException); 
     process.once("uncaughtException", function (error) { 
      recordedError = error 
     }) 
     throwNextTick(error); 
     process.nextTick(function() { 
      process.listeners('uncaughtException').push(originalException) 
      assert.equal(recordedError, error) 
      next() 
     }) 
    }) 
}) 
+1

これはトリックをしましたで!あなたの答えには1つの編集しかありません。アサートがエラーをスローするので、アサートを実行する前に元のリスナーを復元する必要があります。 – Domenic

+0

これは本当にモカのドキュメントにあるはずです!この答えを見つけるのに私は1時間かかりました。Mochaの文書化されていないエラーのキャプチャ(および失敗したテスト)と、標準エラーオブジェクト(Crockfordの助言による)を投げていない場合、エラーメッセージが表示されないという事実テストが失敗している理由を理解することは本当に難しいです。 –

+7

最新バージョンのノード(このコメントの時点ではv0.10.5)では、 'process.listeners(eventName)'はリスナー配列のコピーを返しているので、 'pop()'を呼び出すと実際にはエミッタからリスナーを削除します。 'process.removeListener( 'uncaughtException'、originalException);' –

0

あなたの非同期コードは、ドメイン内で実行であれば - そしてそれはよくあるケースである - あなたの代わりに、プロセスのドメイン上のエラー・リスナーを変更する必要があります。そのために

あなたが使用することができます。

it('should produce an unhandled exception', function (done) { 

    // Remove Mocha's error listener 
    var originalErrorListeners = process.domain.listeners('error'); 
    process.domain.removeAllListeners('error'); 

    // Add your own error listener to check for unhandled exceptions 
    process.domain.on('error', function() { 

     // Add the original error listeners again 
     process.domain.removeAllListeners('error'); 
     for (var i = 0; i < originalErrorListeners.length; i+=1) { 
      process.domain.on('error', originalErrorListeners[i]); 
     } 

     // For the sake of simplicity we are done after catching the unhandled exception 
     done(); 

    }); 

    // This would be your async application code you expect to throw an exception 
    setTimeout(function() { 
     throw new Error(); 
    }); 

}); 
-1

timoxley &ケーシー・フォスターのベース、ノードV6 ++

const assert = require('assert') 

describe('throwNextTick', function() { 
    it('works as expected', function(next) { 

     function cb(err) { 
      assert.equal(err instanceof Error, true) 
      next() 
     } 

     function test(){ 
      process.nextTick(() => { 
       throw new Error('err') 
      }) 
     } 

     process.prependOnceListener('uncaughtException', cb) 
     test() 

    }) 
}) 
+0

この構文( 'import')はNode.jsでは動作しません。 – Domenic

+0

あなたはいつでも '' --require babel-core/register'''でmochaを実行し、 '' import/export'''を行い、.babelrcに '' '"プリセット ":[" es2015 "]}' '' – syarul

関連する問題