> For the complete documentation index, see [llms.txt](https://book.restfulnode.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://book.restfulnode.com/part-3/chapter-10/2-testing-the-middleware.md).

# Testing the Middleware

Recall how the user registration endpoint did not have any middleware. For the purposes of demonstrating how to test a middleware, we'll just be grabbing the `isAuthenticated` middleware that we created and test that instead.

*File: src/middleware/auth.middleware.js*

```javascript
const globalResponseDto = require('../responses/globalResponseDto')

const isAuthenticated = (req, res, next) => {
  if (!req.session.user) {
    return res.status(401).json(
      globalResponseDto({
        status: 'error',
        code: 401,
        message:
          'Access denied: you must be logged in to access this API endpoint.',
        data: null,
        errors: ['You must be logged in.']
      })
    )
  }

  next()
}

module.exports = isAuthenticated
```

Testing the middleware is a lot trickier than just a regular function. This reason why is because we are expected to stick to a particular function signature `(req, res, next)`.

The answer to this is to mock out those particular parameters. The way to do it is to use `jest.fn`, which we will use to help us write out helpers like `mockRequest`, `mockResponse`, and `mockNext` functions.

*File: src/middleware/\_\_tests\_\_/auth.middleware.test.js*

```javascript
const isAuthenticated = require('../auth.middleware')
const globalResponseDto = require('../../responses/globalResponseDto')

const mockRequest = (userData) => ({
  session: {
    user: userData
  }
})

const mockResponse = () => {
  const res = {}

  res.status = jest.fn().mockReturnValue(res)
  res.json = jest.fn().mockReturnValue(res)

  return res
}

const mockNext = () => {
  return jest.fn()
}

describe('Test Suite: isAuthenticated middleware', () => {
  // our tests go here...
})
```

### The Passing Test

Now watch as we pass the `mockRequest`, `mockResponse`, and `mockNext` functions into our `isAuthenticated` function. If everything goes well, then we should expect the `next` to be invoked.

```javascript
test('Access granted, next() should be invoked in express', async () => {
  // 1. Arrange
  const req = mockRequest({ first_name: 'john' })
  const res = mockResponse()
  const next = mockNext()

  // 2. Act
  await isAuthenticated(req, res, next)

  // 3. Assert
  expect(next).toHaveBeenCalled()
})
```

### The Passing Test

Now for the failing test, we should expect the correct status code and output.

```javascript
test('Access denied, respond with a status 401', async () => {
  // 1. Arrange
  const req = mockRequest()
  const res = mockResponse()

  // 2. Act
  await isAuthenticated(req, res)
  
  // 3. Assert
  expect(res.status).toHaveBeenCalledWith(401)
  expect(res.json).toHaveBeenCalledWith(
    globalResponseDto({
      status: 'error',
      code: 401,
      message:
        'Access denied: you must be logged in to access this API endpoint.',
      data: null,
      errors: ['You must be logged in.']
    })
  )
})
```
