I can't access modified window.location object jest in another module

Viewed 109

I want to mock window.location.search.

config.test.js

import config from './config'
import { MULTIPLE_VIDEOS } from './Constants/flagKeys'

describe('', () => {
  const flag = { [MULTIPLE_VIDEOS]: true }

  global.window = Object.create(window)

  Object.defineProperty(window, 'location', {
    value: {}
  })

  afterAll(() => {
    global.window = null
  })

  it('Mark query string flag as true', () => {
    global.window.location.search = `?${MULTIPLE_VIDEOS}=true`
    expect(config.flags).toEqual(flag)
  })
})

config.js

export default { flags: getFlagsFromQueryString() }

function getFlagsFromQueryString () {
  const queryString = qs.parse(window.location.search.slice(1))
  const flags = {}

  Object.entries(queryString).forEach(([name, value]) => {
    flags[name] = value.toLowerCase() === 'true'
  })

  return flags
}

Though I set search value in location object before calling config.flags, I can't access it inside the function, It always returns empty string.

I want window.location.search.slice(1) to return ?multipleVideos=true inside getFlagsFromQueryString function instead of empty string, since I changed the value in the test file.

One thing I noticed, when I export the function and call in the test file it works.

1 Answers

For this type of complex uses. I would recommend you to create a Window service/util class and expose methods from there. easy to test and mock.

Sample:

// Window.js

class Window {
  constructor(configs) {}
  navigate(href) {
    window.location.href = href;
  }
}
export default new Window({});

Now you can easily mock Window.js. It is similar to DI pattern.

Related