最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - How to test the args passed into document.body.appendChild with jest - Stack Overflow

programmeradmin2浏览0评论

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?

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?

Share Improve this question asked Mar 14, 2019 at 14:59 Christopher MooreChristopher Moore 3,0995 gold badges32 silver badges46 bronze badges
Add a comment  | 

3 Answers 3

Reset to default 14

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!
});

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));

Another option is to use jest's (optionally inline)snapshots:

it('...', () => {
  doFunction()
  expect(document.documentElement).toMatchInlineSnapshot(`
      <html>
        <head>
          <!-- ...your appended nodes... -->
        </head>
        <body>
          <!-- ...your appended nodes... -->
        </body>
      </html>
    `)
})
发布评论

评论列表(0)

  1. 暂无评论