Search code examples
javascriptnode.jsaws-lambdajestjsmiddy

how to unit test if handler function is called when using middy


im using an http request function as the handler function in middy and then use the ssm middleware to fetch some ssm parameters before initiating the http request. like this:

  const makeThirdPartyServiceRequest = middy(async ({ params }) => {
  logger.info(`SENDING Request to ${endpoint} API`)
  const url = `https://someurltoathirdpartyservice`
  const options = {
    method: 'POST',
    body: params
  }

  return helpers.makeRequest(url, options)
})
makeThirdPartyServiceRequest.use(ssm(......))

However in my jest unit test Im trying to mock makeThirdPartyServiceRequest and explicitly say it should resolve to a value:

jest.mock('../src/thirdPartyService', () => ({
  __esModule: true,
  default: {
    ...(jest.requireActual('../src/thirdPartyService') as { default: {} }).default,
    makeThirdPartyServiceRequest: jest.fn()
  }
}))
export {}
import thirdPartyService from '../src/thirdPartyService'

And then in the test i say:

describe('makeThirdPartyServiceRequest()', () => {
  it('should makeThirdPartyServiceRequest', async () => {
    // Given

    // })
    const mockedThirdPartyServiceRequest = mocked(thirdPartyService.makeThirdPartyServiceRequest).mockResolvedValue({})
    // When
    const result = await thirdPartyService.makeThirdPartyServiceRequest(something)
    // Then
    expect(mockedThirdPartyServiceRequest).toHaveBeenCalledTimes(1)
    expect(mockedThirdPartyServiceRequest.mock.calls[0][0].params.toString()).toBe(expectedParams)
  })
})

However for some reason the middy middleware is still being invoked, which i clearly dont want and i have tried to mock away... what am i doing wrong?


Solution

  • You need to mock middy instead, to make it becomes a useless function. That function recipe a function as a parameter and return that parameter.

    import thirdPartyService from '../src/thirdPartyService'
    
    jest.mock('@middy/core', () => {
      return (handler) => {
        return {
          use: jest.fn().mockReturnValue(handler), // ...use(ssm()) will return handler function
        }
      }
    })
    
    describe('thirdPartyService()', () => {
      beforeEach(() => {
        jest.spyOn(helpers, 'makeRequest') // spy on helpers unit
      })
    
      describe('makeThirdPartyServiceRequest', () => {
        it('should make a request with correct parameters', async () => {
          // Given
          const url = `https://someurltoathirdpartyservice`
          const params = 'any params'
          const apiResponse = 'any response'
          mocked(helpers.makeRequest).mockResolvedValue(apiResponse)
    
          // When
          const actual = await thirdPartyService.makeThirdPartyServiceRequest(params)
    
          // Then
          expect(actual).toBe(apiResponse)
          expect(helpers.makeRequest).toHaveBeenCalledWith(
            url,
            {
              method: 'POST',
              body: params
            }
          )
        })
      })
    })