Extending Jest's "Automatic Mock" functionality

Viewed 650

Context

Jest's "automatic mocking" functionality is very useful. I don't have to create handwritten mocks for every class, I can just do:

jest.mock('./src/MyObject')

... and I have a mock object that has all the right functions, all mocked out.

Note that I am not referred to the "automock" feature, which takes this to another level by not even requiring you to call jest.mock(), but rather the automatic functionality that occurs when you call jest.mock() without passing a mock factory (i.e. when passing only one argument).

Goal

I want to be able to customize this automatic mocking behavior slightly without losing all of the magic above. For context, I am trying to make Jest play nicely with third-party framework, but here are some simplified requirements:

  • Drop-in replacement. You still call jest.mock(), you still import classes normally, etc. Test writers are oblivious to the customization.
  • All of the functions of the target object still automatically mocked. If I add functions to that object, I don't need to update the mock.
  • If the target object has a function named awesomeFunction(), I want it to be automatically mocked to return the string "awesome". (contrived example alert!)

Where I'm stuck

I've managed to create a function that uses jest.genMockFromModule() which invokes this automatic mocking behavior. I can then modify this mock as I see fit (e.g. mocking awesomeFunction()). Finally I can register this mock using jest.setMock().

I can now use this function (let's call it mockAwesomely()) in my test code:

import MyModule from './src/MyModule'
mockAwesomely('./src/MyModule') // used to be jest.mock('./src/MyModule')

The problem is, with this code, the imported MyModule is not the mocked module. It's the real MyModule. After some investigation, I believe this is happening because mockAwesomely() is not being hoisted to the top of the file like jest.mock() is. Even manually putting it at the top of the file doesn't seem to work, because import statements are hoisted too.

I feel like I'm really close. Any suggestions on how to proceed?

0 Answers
Related