Unit testing with Supertest, Mocha & Sinon timing out

I am trying to write a unit/integration test where I want to get a list of things in the database. For not it is only a GET, but these tests needs to extend to POST, PUT & DELETE.

The code I have thus far works fine, I can actually get data from the DB, but as soon as I try to stub out the function which is responsable for making the call to the DB, Mocha times out

1 failing

1) /account_types GET 200 List:
Error: timeout of 2000ms exceeded. Ensure the done() callback is being called in this test.
at null. (C:\Code\JS\general_admin_service\node_modules\mocha\lib\runnable.js:215:19)

I understand the done() callback isn't being called because the code is stuck somewhere, however, I do not understand what I am doing wrong.

As you already make clear in the comments, it's difficult to test code that's deeply nested.

It's usually much better to work with callbacks or promises, so that each piece of your app will handle the part it's responsible for, but not (much) more. So your route handler will handle the request and the response. It's obviously okay to call other functions, like ones that perform database queries, but instead of letting those functions send back a response, you use callbacks that "call back" to the route handler with the query results.

In terms of using Sinon to test something like this: it really depends on the exact implementation. I can provide a quick example on how to stub the above usage of select.query_list, to make sure that the response contains the correct data.

What this does, is when select.query_list() gets call, it will call the first callback argument it receives (it does this by checking each argument to see which is a function) with the arguments null, [ { id : 'test' } ].

Those are the err and records arguments of the callback function passed in the handler. So you can use this to skip the database query entirely and pretend that the query yielded a particular array of records.

From there, res.send() gets called (which was the issue that you initially ran into: it didn't get called at all because it was being performed in a part of your app that wasn't getting called because of your stub) and you can check in your test if the resulting response data is as expected.

It becomes a bit more complicated if you want to stub a function deeper in the call stack, but with the correct Sinon tools (like .yields*, or using spies instead of stubs) it's usually not terribly difficult (provided that all the functions that you want to stub/spy are accessible, that is, exported).