user866364
user866364

Reputation:

Jest - mock a property and function from moment-timezone

Im trying to mock property tz and a function using jest but i dont know to mock both things together:

If run something like:

jest.mock('moment-timezone', () => () => ({weekday: () => 5}))

jest.mock('moment-timezone', () => {
  return {
    tz: {

    }
  }
})

I can mock attribute tz or instruction moment(). How can i write a mock for cover this code?

const moment = require('moment-timezone')

module.exports.send = () => {
  const now = moment()
  moment.tz.setDefault('America/Sao_Paulo')
  return now.weekday()
}

Thanks

Upvotes: 5

Views: 6858

Answers (1)

miqh
miqh

Reputation: 3664

You could take advantage of the second parameter of jest.mock(), which would let you specify a custom implementation of the mocked module to use in testing.

Inside this custom implementation, you can also define some convenience helpers to emulate expected implementation values (e.g. weekday()).

// send-module.test.js

jest.mock('moment-timezone', () => {
    let weekday
    const moment = jest.fn(() => {
        return {
            weekday: jest.fn(() => weekday),
        }
    })
    moment.tz = {
        setDefault: jest.fn(),
    }
    // Helper for tests to set expected weekday value
    moment.__setWeekday = (value) => weekday = value
    return moment;
})

const sendModule = require('./send-module')

test('test', () => {
    require('moment-timezone').__setWeekday(3)
    expect(sendModule.send()).toBe(3)
})

Do note that manually providing the mock per test file can get tedious and repetitive if the module being mocked has a huge API surface. To address the latter case, you can consider authoring some manual mocks to make them reusable (i.e. using the __mocks__ directory convention) and supplement that by using jest.genMockFromModule().

The Jest documentation has some guidance about this.

Upvotes: 5

Related Questions