Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

how to unmock a single instance method with jest

coming from rspec, i am having trouble understanding mocking with jest. the approach i am trying for, is to automock a class's constructor and all of it's functions, and then unmock them one by one to test only that one function. the only documentation i can find on it, is with using 2 classes, mocking 1 class, and then testing that those functions are called from the other unmocked class.

below is a basic, contrived idea of what i am trying to do. can someone direct me to the jest-way of doing this?

foo.js

class Foo
  constructor: ->
    this.bar()
    this.baz()
  bar: ->
    return 'bar'
  baz: ->
    return 'baz'

foo_test.js

// require the class
Foo = require('foo')

// mock entire Foo class methods
jest.mock('foo')

// unmock just the bar method
jest.unmock(Foo::bar)

// or by
Foo::bar.mockRestore()

// and should now be able to call
foo = new Foo
foo.bar() // 'bar'
foo.baz() // undefined (still mocked)

// i even tried unmocking the instance
foo = new Foo
jest.unmock(foo.bar)
foo.bar.mockRestore()
like image 364
brewster Avatar asked Jan 09 '19 12:01

brewster


2 Answers

mockFn.mockRestore() worked for me with [email protected]:

// Create a spy with a mock
const consoleInfoSpy = jest.spyOn(console, 'info').mockImplementation(() => {})

// Run test or whatever code which uses console.info
console.info('This bypasses the real console.info')

// Restore original console.info
consoleInfoSpy.mockRestore()
like image 65
Nick Ribal Avatar answered Sep 19 '22 18:09

Nick Ribal


This does not strictly apply to the OP, but answer-seekers may end up here. You can mock a module except certain parts for all tests like so.

mocks/saladMaker.js

// Let Jest create the mock.
const saladMaker = jest.genMockFromModule('../saladMaker');

// Get the unmocked chop method.
const {chop} = require.requireActual('../saladMaker');

// Patch it in.
saladMaker.chop = chop;

module.exports = saladMaker;

The key part is to use requireActual to get at the unmocked module.

bypassing module mocks

Update

require.requireActual has been replaced with jest.requireActual.

like image 20
reergymerej Avatar answered Sep 21 '22 18:09

reergymerej