testdouble / quibble

Makes it easy to replace require'd dependencies.
94 stars 25 forks source link

Mocking native esm modules on fastify project fails #42

Open anonrig opened 3 years ago

anonrig commented 3 years ago

Hi everyone!

First of all thank you for everything related to testdouble. I'm having some trouble regarding a esm import in a fastify project I've been working on.

Here's the example code. getByAuthorization is a function called inside the prehandler middleware of a fastify endpoint. And the issue is, the function is not replaced, without giving any error or indication of the reason.

test('should throw forbidden on wrong x-key', async (t) => {
  await quibble.esm(
    path.join(path.resolve(''), '../src/models/application.js'),
    {
      getByAuthorization: async function () {
        return null
      },
    },
  )

  const { statusCode, body } = await server.inject({
    method: 'POST',
    url: '/v1/events',
    payload: [{ name: 'non-existent', timestamp: Date.now() }],
    headers: {
      'x-key': v4(),
      'x-client-id': v4(),
    },
  })
  const response = JSON.parse(body)

  t.is(statusCode, 403)
  t.is(response.error, 'Forbidden')
  t.truthy(response.message.includes('Invalid authorization key'))
})
searls commented 3 years ago

whenever I hear ESM, I tag in @giltayar!

giltayar commented 3 years ago

Will look into it tonight.

giltayar commented 3 years ago

@anonrig you're import-ing the server before you're quibble.esm-ing, right? So that means that the server is importing application.js before you're quibble-ing, which means it gets the unimported version of the application. This would happen even if you use CJS.

To deal with that, await import the server after you quibble.esm. I may be misunderstanding, but I believe that's the problem.

BTW, td.replaceEsm is the same as quibble.esm. You don't really need to use quibble (although it's still fine).

anonrig commented 3 years ago

Here I am, 6 months later, tackling with the same issue after solving it 6 months ago. 🗡️