Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why is Jest still requiring a mocked module?

I am mocking a module using Jest because it contains code that shouldn't run in the test. However I can see from the output that code in the module is being run.

// foo.js
console.log('Hello')

// test.js
jest.mock('./foo')
const foo = require('./foo')

test.todo('write some tests')

Console output

PASS  test.js
  ✎ todo 1 test

console.log foo.js:1
Hello

What's up with that?

like image 561
Tamlyn Avatar asked Apr 11 '19 12:04

Tamlyn


People also ask

What is Jest mocked?

Mocking is a technique to isolate test subjects by replacing dependencies with objects that you can control and inspect. A dependency can be anything your subject depends on, but it is typically a module that the subject imports.

What is __ mocks __ in Jest?

Mocking Node modules​ If the module you are mocking is a Node module (e.g.: lodash ), the mock should be placed in the __mocks__ directory adjacent to node_modules (unless you configured roots to point to a folder other than the project root) and will be automatically mocked. There's no need to explicitly call jest.

Is useful when you want to completely restore a mock back to its initial state?

mockClear() does, and also removes any mocked return values or implementations. This is useful when you want to completely reset a mock back to its initial state. (Note that resetting a spy will result in a function with no return value).


1 Answers

This has tripped me up a couple of times.

If you don't provide a mock implementation to jest.mock it will return an object which mirrors the exports of the mocked module but with every function replaced with a mock jest.fn(). This is pretty neat as it is often what you want. But in order to determine the exports of the module, it must first require it. This is what is causing the console.log to be run.

Two possible solutions:

  • Don't run code in the top level of the module: instead export a function which runs the code.
  • Provide your own mock implementation so it doesn't need to introspect the module jest.mock('./foo', () => {})
like image 95
Tamlyn Avatar answered Oct 16 '22 20:10

Tamlyn