Faking errors to test error scenarios in Express API's
Tags: node, javascript, testing
Published: 2020-02-13 17:13:11

---
title: Faking errors to test error scenarios in Express API's
published: true
canonical_url: https://www.coreycleary.me/faking-errors-to-test-error-scenarios-in-express-apis/
tags: node,javascript,testing
---

<em><strong>Originally published at <a href="https://www.coreycleary.me/faking-errors-to-test-error-scenarios-in-express-apis/">coreycleary.me</a></strong>. This is a cross-post from my content blog. I publish new content every week or two, and you can <a href="https://www.coreycleary.me/about/">sign up to my newsletter</a> if you'd like to receive my articles directly to your inbox! I also regularly send cheatsheets and other freebies.</em>


You've written tests for your Express app.

You've got most "happy path" test cases covered. Under normal circumstances, your API works as expected.

But now you need to write a test for how your API handles an error. You want to test that your API returns a HTTP <code>500</code> status code, for example, if there is an internal server error.

The problem is... under normal circumstances your code doesn't encounter an error scenario...

So, how do you trigger one so you can write that test and get on with writing actual <strong>app</strong> code? Instead of spinning your wheels figuring out how to write the <strong>test</strong> code!

This is where stubs come into play. Let's go over that now.
<h3>Faking an error</h3>
You might have heard the terms <strong>spy</strong>, <strong>stub</strong>, or <strong>mock</strong> before. We'll call these collectively <strong>fakes</strong>.

The specific fake we want to use here is a <strong>stub</strong> - this will allow us to override the function we want to trigger an error for, so we can test our Express response status.

In this case, let's say we want to test that our REST API returns a <code>500</code> error code when called.

Let's imagine we have a route <code>/api/search</code>, that makes a call to a database. We want to see what happens when that database call throws an error. When that "bubbles up" to the Express route, what is returned by Express?

In our app the flow of code goes <code>HTTP request</code> ---&gt; <code>Express route</code> ---&gt; <code>Controller</code> ---&gt; <code>Service</code> ---&gt; <code>Database</code>

Our database code looks like this:
```javascript
const search = async (term, numToFetch = null) =&gt; {
  return db.select('*').from('item').where('name', 'like', `%${term}%`).limit(numToFetch)
}

export {
  search
}
```
<code>search</code> gets called by the service, which is called by the controller, which is called by the route.
<h3>Sinon to the rescue</h3>
So how do we actually use a stub to fake an error?

This is where <a href="https://sinonjs.org/releases/v7.5.0/stubs/" rel="noopener" target="_blank">sinon</a> and its stubbing ability comes to the rescue.

We can "fake" an error using sinon by doing something like:
```javascript
sinon.stub(module, 'functionToStub').throws(Error('error message'))
```
So in our case, the Express route test would look like so:
```javascript
import request from 'supertest'
import sinon from 'sinon'
import app from '../../app'
import * as itemQueries from '../../db/queries/item.query'

describe('/api/search route', () =&gt; {
  it('should return a 500 when an error is encountered', async () =&gt; {
    // stub an error
    sinon.stub(itemQueries, 'search').throws(Error('db query failed'))

    await request(app) // pass Express app to supertest
      .post('/api/search') // call Express route we want to test
      .send({term: 'blah', num: 1}) // pass normally expected, valid data in request body
      .expect(500) // assert that we return a HTTP 500 response status code
  })
})
```

In the above test, we assert on the status code - <code>.expect(500)</code> - because if the database query fails and throws an error (maybe the database is down, for example), we expect to return a <a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/500" rel="noopener" target="_blank">500 Internal Server</a> error code to the caller of the API.
<h3>Wrapping up</h3>
By stubbing a fake error in the test code, you're able to avoid hardcoding an error in your app code <strong>and</strong> mimic a real-world error scenario.

With that test case covered, this gives your app much more reliability.

And you don't just have to fake an error at the database layer, you can do it anywhere within your app. You can even <a href="https://www.coreycleary.me/real-world-testing-recipes-node-service-that-calls-an-external-api/" rel="noopener" target="_blank">mock calls to external services you don't own!</a>

Love JavaScript but still getting tripped up by unit/integration tests? I publish articles on JavaScript and Node every 1-2 weeks, so if you want to receive all new articles directly to your inbox, <a href="https://www.coreycleary.me/about/">here's that link again</a> to subscribe to my newsletter!