Home > Net >  Getting undefined error when operating on a mocked window navigator object
Getting undefined error when operating on a mocked window navigator object

Time:10-15

I have the following component where on button click, I am looking to perform a copy to clipboard for the text value.

This is working fine and looking to write a test for it. But currently with my test, keep getting following error:

Error: Uncaught [TypeError: Cannot read property 'then' of undefined]

Also tried other examples suggested here with same outcome.

How to mock navigator.clipboard.writeText() in Jest?

Could I please get some help on what I am doing wrong pls. Thanks.

My Component

import React, { useState } from 'react';
import { Button } from '../../Button';

const A = ({
  text,
}) => {
  const [copyStatus, setCopyStatus] = useState('');
  const onClick = () => {
    window.navigator.clipboard.writeText(text)
      .then(() => {
        setCopyStatus('yes');
      })
      .catch(() => setCopyStatus('no'));
  };

  const CopyBtn = () => (
    <Button onClick={onClick}>
      Click
    </Button>
  );

  return (<div>
    {CopyBtn}
  </div>);
};

export default A;

My Test

import React from 'react';
import { mount } from 'enzyme';
import A from '../../../src/components/A';

jest.mock('../../Button', () => ({
  Button: 'button',
}));

Object.defineProperty(navigator, "clipboard", {
  value: {
    writeText: () => {},
  },
});

jest.spyOn(navigator.clipboard, "writeText");

describe('A component test', () => {
  const props = {
    text: 'mock',
  };

  it('should copy to clipboard as expected', () => {
    const renderedModule = mount(<A {...props} />);

    // simulate does work. Which triggers the attempt to call navigator.clipboard.writeText and fails. 
    renderedModule.find('button').simulate('click');
    expect(navigator.clipboard.writeText).toBeCalledTimes(1);
  });
});

CodePudding user response:

The mock function is getting actually called and it needs to return a Promise.

You could use jest.fn to mock the function behaviour.

Object.defineProperty(navigator, "clipboard", {
  value: {
    // Provide mock implementation
    writeText: jest.fn().mockReturnValueOnce(Promise.resolve(42)),
  },
});

Then you don't need to call jest.spyOn it.

  • Related