I have the following function:
Code to test
export default function main() { const createAndAppendPTag = () => { const p = document.createElement('p'); document.body.appendChild(p); }; window.document.addEventListener('click', () => { createAndAppendPTag(); }); }
The question is: How can I assert using Jest that createAndAppendPTag
was called upon a document click event ?
Jest
This is what I tried, but can’t seem to make the test pass:
import main from './main' window.document.addEventListener = jest.fn(); const createAndAppendPTag = jest.fn(); describe('Main', () => { const documentClickEvent = new Event('click'); test('appends p tag to the document', () => { // dispatching event before and after invoking `main` to be sure window.document.dispatchEvent(documentClickEvent); main(); window.document.dispatchEvent(documentClickEvent); expect(window.document.addEventListener).toHaveBeenNthCalledWith(1, 'click', () => {}); expect(createAndAppendPTag).toHaveBeenCalledTimes(1); }); });
Terminal
This results in the following:
🔴 Main › appends p tag to the document expect(jest.fn()).toHaveBeenNthCalledWith(n, ...expected) n: 1 Expected: "click", [Function anonymous] Number of calls: 0 5 | main(); 6 | window.document.dispatchEvent(documentClickEvent); > 7 | expect(window.document.addEventListener).toHaveBeenNthCalledWith(1, 'click', () => {}); * | ^
Thanks in advance.
Advertisement
Answer
I ran this simplified test to check for the side effect (p
element was appended to body):
main.js
export default function main() { const createAndAppendPTag = () => { const p = document.createElement('p'); document.body.appendChild(p); }; window.document.addEventListener('click', () => { createAndAppendPTag(); }); }
main.test.js
import main from `../main.js`; it('"main" listener appends "P" to body upon click', () => { // add listener main(); // clear body contents document.body.innerHTML = ""; // dispatch click event to listener const addEvt = new Event('click'); document.dispatchEvent(addEvt); // check for existence of "P" element const bodyEl = document.body.firstChild; expect(bodyEl).not.toEqual(null); expect(bodyEl.tagName).toBe('P'); document.body.innerHTML = ""; });
It passed:
✓ "main" listener appends "P" to body upon click (2 ms)