Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to test the args passed into document.body.appendChild with jest

I have a function that creates a script element and adds it to the body. It looks a bit like this:

const s = document.createElement('script');
s.type = 'text/javascript';
s.src = 'https://myscript';
s.id = 'abc';

document.body.appendChild(s);

I'm using testing using jest and am spying on the appendChild function to assert that the parameters passed in are what I expect. What I have looks like this:

jest.spyOn(document.body, 'appendChild');

doFunction();

expect(document.body.appendChild).toBeCalledWith(
  '<script id="abc" src="https://myscript" type="text/javascript" />',
);

Despite the strings matching, the argument that gets passed into appendChild isn't a string, but an object.

typeof document.body.appendChild.mock.child[0][0] // object

I've also tried asserting against an object ({ type: '...' } with no luck. What other options are there with jest to test this bit of code?

like image 478
Christopher Moore Avatar asked Mar 14 '19 14:03

Christopher Moore


2 Answers

As @Alex points out, document.createElement creates an HTMLScriptElement object.

You can test that the HTMLScriptElement was created properly by checking its properties using expect.objectContaining:

const doFunction = () => {
  const s = document.createElement('script');
  s.type = 'text/javascript';
  s.src = 'https://myscript';
  s.id = 'abc';

  document.body.appendChild(s);
}

test('doFunction', () => {
  jest.spyOn(document.body, 'appendChild');

  doFunction();

  expect(document.body.appendChild).toBeCalledWith(
    expect.objectContaining({
      type: 'text/javascript',
      src: 'https://myscript/',
      id: 'abc'
    })
  ); // Success!
});
like image 101
Brian Adams Avatar answered Oct 11 '22 18:10

Brian Adams


You can assert that appendChild is called with an HTML element, which is what document.createElement returns.

expect(document.body.appendChild).toBeCalledWith(expect.any(HTMLElement));

You can further clarify your test by checking that it was called with a script element.

expect(document.body.appendChild).toBeCalledWith(expect.any(HTMLScriptElement));
like image 27
Alex Robertson Avatar answered Oct 11 '22 16:10

Alex Robertson