From a24683fd9273d0896a177d70c2368ada4f2c4882 Mon Sep 17 00:00:00 2001 From: Zirak Date: Sun, 19 Jan 2020 14:22:46 +0200 Subject: [PATCH] Throw a descriptive error when a non-function is given to a runnable (#4133) Given a test such as: ```js it('foobars', 4); ``` mocha used to throw the following error: `fn.call is not a function`. While technically true, I have personally spent some minutes of my life chasing what looked like a bug in the test itself, and not in the call to `it`. A more descriptive error message helps bring attention to where the problem originates. (Thanks to [ssube](https://github.com/ssube) for helping with the error wording.) --- lib/runnable.js | 9 +++++++++ test/unit/runnable.spec.js | 14 ++++++++++++++ 2 files changed, 23 insertions(+) diff --git a/lib/runnable.js b/lib/runnable.js index 2d0c428d46..0346b36346 100644 --- a/lib/runnable.js +++ b/lib/runnable.js @@ -338,6 +338,15 @@ Runnable.prototype.run = function(fn) { // for .resetTimeout() this.callback = done; + if (this.fn && typeof this.fn.call !== 'function') { + done( + new TypeError( + 'A runnable must be passed a function as its second argument.' + ) + ); + return; + } + // explicit async with `done` argument if (this.async) { this.resetTimeout(); diff --git a/test/unit/runnable.spec.js b/test/unit/runnable.spec.js index 40ccc12c7e..2c079c3b40 100644 --- a/test/unit/runnable.spec.js +++ b/test/unit/runnable.spec.js @@ -670,6 +670,20 @@ describe('Runnable(title, fn)', function() { }); }); }); + + describe('when fn is not a function', function() { + it('should throw an error', function() { + var runnable = new Runnable('foo', 4); + + runnable.run(function(err) { + expect( + err.message, + 'to be', + 'A runnable must be passed a function as its second argument.' + ); + }); + }); + }); }); describe('#isFailed()', function() {