Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to use doMock in jest?

I find that when using jest.doMock instead of jest.mock to mock a function (I will need to create multiple mock implementations for the same function in different it blocks), I find that the test fails with

Error

expect(jest.fn()).toBeCalled()

Expected mock function to have been called.

Also, if I require the module at the top of the test instead of doing it within the same it block, it gives me a different error:

expect(jest.fn())[.not].toBeCalled()

jest.fn() value must be a mock function or spy.
Received:
  function: [Function headObject]

Code

  1. headObject(Collaborator being mocked)

    // NOT IMPLEMENTED YET
    module.exports = function() {}
    
  2. Test code

    it('checks to see if a resource exists when given a threshold', () => {
      jest.doMock('../s3/headObject', () => {
        return jest.fn(() => {})
      })
      const headObject = require('../s3/headObject')
      handler(event.correct_uses_propertyId_withExplicitThreshold, {}, () => {})
      expect(headObject).toBeCalled()
    })
    
  3. Source Code

    const headObject  = require('../s3/headObject')
      module.exports = async function(event, context, callback) {
       headObject()
    }
    

Previously

I used environment variables to change the mock implementation using mocks within __mocks__ like this:

const result = jest.genMockFromModule('../realModule.js')
const mockResponse = require('../../eventMocks/realModuleName/fixture.json')

function mock (bearerToken, address) {
  if (process.env.DONT_USE_TEST_ONLY_EMPTY_ESTIMATE) {
    return {
      history: []
    }
  }
  return mockResponse
}

result.mockImplementation(mock)

module.exports = result

and in my test, I would:

it('does not store empty results in S3', () => {
  process.env.DONT_USE_TEST_ONLY_EMPTY_ESTIMATE = true
  const res = LambdaTester(handler)
  .event(event.correct_uses_address)
  .expectResult(r => {
    expect(r.statusCode).toEqual(404)
    const body = JSON.parse(r.body)
    expect(body.message).toEqual(NO_ESTIMATE)
  })

  process.env.DONT_USE_TEST_ONLY_EMPTY_ESTIMATE = false
  return res
})
like image 669
vamsiampolu Avatar asked Mar 14 '18 00:03

vamsiampolu


People also ask

How do you use mock method in Jest?

The simplest and most common way of creating a mock is jest. fn() method. If no implementation is provided, it will return the undefined value. There is plenty of helpful methods on returned Jest mock to control its input, output and implementation.

How do you mock in Jest test?

There are two ways to mock functions: Either by creating a mock function to use in test code, or writing a manual mock to override a module dependency.

What are Jest mocks?

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.


1 Answers

Late to the party.... doMock is a pain. We use this setup within our tests:

// import function from module you want to mock
import getClientVersion from '../api/clientVersion';

// mock the whole module
jest.mock('../api/clientVersion');


// within a test, overwrite that specific function
getClientVersion.mockResolvedValueOnce(1);

Good thing with this is, that you can easily change the setup in each test.

Hope this helps someone who stumbles upon this questions

like image 176
flaky Avatar answered Sep 22 '22 05:09

flaky