# 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.']
    })
  )
})
```


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://book.restfulnode.com/part-3/chapter-10/2-testing-the-middleware.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
