Why all the async functions seem like they are not covered branches in Jest/Istanbul coverage report?

Viewed 678

I have this all over my application: I have a well covered function, however it says "branch not covered" on async function part in test coverage report generated by Istanbul after running Jest test coverage script.

What does this mean? How can I cover it?

I don't understand what is not covered in these functions.

Test example for "getPolicyStatsAPI" function: The rest of the functions are tested the same way. I don't believe the answer is in the test suites. But if needed I can share the rest.

  describe(`API Calls`, () => {
    const mockFetch = jest.fn()
    global.fetch = mockFetch
    beforeEach(() => {
      mockFetch.mockClear()
    })
    test('getPolicyStatsAPI fetches the data and returns it as expected', async () => {
      mockFetch.mockReturnValueOnce(createAPIResponse(policySearchState))

      const response = await getPolicyStatsAPI(reqBody)
      expect(fetch).toBeCalledTimes(1)
      expect(response).toEqual(policySearchState.data)
    })
    test('getPolicyStatsAPI returns error on exception', async () => {
      const error = new Error(errorMessage)
      // eslint-disable-next-line prefer-promise-reject-errors
      mockFetch.mockImplementationOnce(() => Promise.reject(errorMessage))
      await expect(getPolicyStatsAPI(reqBody)).rejects.toEqual(error)
      expect(fetch).toBeCalledTimes(1)
    })
  })

Here is the code I get "branch not covered" warning on: Branch not covered warning appears right over "async function" part of the code, and only there, as a yellow highlight.

export async function getPolicyStatsAPI(reqBody: APIRequestBody) {
  const body: APIRequestBody = {
    ...reqBody,
  }
  type ExpectedResponse = { data: PolicyStats[] }
  const response = await callAPI<ExpectedResponse>({
    url: Endpoint.POLICY_STATS,
    method: 'POST',
    body,
  })
  return response.data
}

Image of test coverage report:

enter image description here

2 Answers

after leaving the comment I tried some other fixes myself, and apparently removing the transform key in my jest.config.js fixed the issue:

module.exports = {
  ...
  globals: {
    'ts-jest': {
      tsconfig: 'tsconfig.test.json',
      babelConfig: 'babel.config.js'
    },
  },

  // Removed this part:
  // transform: {
  //   '^.+\\.js$': '<rootDir>/node_modules/babel-jest',
  //   '^.+\\.(ts|tsx)?$': 'ts-jest',
  // },

  moduleNameMapper: {
    '\\.(jpg|jpeg|png|gif|eot|otf|webp|svg|ttf|woff|woff2|mp4|webm|wav|mp3|m4a|aac|oga)$':
      'identity-obj-proxy',
  },
  ..
}

Not sure if it's the same with your project, but you could give it a try.

Every async function needs an await:

    mockFetch.mockReturnValueOnce(await createAPIResponse(policySearchState))

    const response = await getPolicyStatsAPI(reqBody)

    expect(response).toEqual(await policySearchState.data)

    await expect(await getPolicyStatsAPI(reqBody)).rejects.toEqual(error)
Related