Jest – Mock Window or Document object

2019-07-19 15:22发布

问题:

How do you mock (and then test) the Window or Document object with Jest? Especially when it has nested functions that may not yet defined in the file you're testing E.g.

const foo = (payload) => {
    window.webkit.messageHandlers.execute.postMessage(payload)
    return true
}

// Jest: TypeError: Cannot read property 'messageHandlers' of undefined'

Similarly, how would you mock document.location? E.g.

const bar = (nonce, payload) => {
    document.location = 'native://somefeature/send?nonce=' + nonce + '&payload=' + payload
    return true
}

I was going in the direction of:

describe('foo', () => {
  it('posts a message', () => {
    const payload = 'payload'
    window.webkit.messageHandlers.execute.postMessage = jest.fn()
    let result = foo(payload) 
    expect(window.webkit.messageHandlers.execute.postMessage).toHaveBeenCalledWith(payload)
  })    
})

I'm guessing you'd do something similar for document.location =. But of course that would be way too easy, and it does not work.

回答1:

If you haven't found an answer already, you should be able to mock it like this:

  postMessageMock = jest.fn();
  Object.defineProperty(window, 'webkit', {
    value: { messageHandlers: { execute: { postMessage: postMessageMock } } },
  });