I have the following function:
Code to test
JavaScript
x
11
11
1
export default function main() {
2
const createAndAppendPTag = () => {
3
const p = document.createElement('p');
4
document.body.appendChild(p);
5
};
6
7
window.document.addEventListener('click', () => {
8
createAndAppendPTag();
9
});
10
}
11
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:
JavaScript
1
21
21
1
import main from './main'
2
3
window.document.addEventListener = jest.fn();
4
const createAndAppendPTag = jest.fn();
5
6
describe('Main', () => {
7
const documentClickEvent = new Event('click');
8
9
test('appends p tag to the document', () => {
10
// dispatching event before and after invoking `main` to be sure
11
window.document.dispatchEvent(documentClickEvent);
12
13
main();
14
15
window.document.dispatchEvent(documentClickEvent);
16
17
expect(window.document.addEventListener).toHaveBeenNthCalledWith(1, 'click', () => {});
18
expect(createAndAppendPTag).toHaveBeenCalledTimes(1);
19
});
20
});
21
Terminal
This results in the following:
JavaScript
1
14
14
1
🔴 Main › appends p tag to the document
2
3
expect(jest.fn()).toHaveBeenNthCalledWith(n, expected)
4
5
n: 1
6
Expected: "click", [Function anonymous]
7
8
Number of calls: 0
9
10
5 | main();
11
6 | window.document.dispatchEvent(documentClickEvent);
12
> 7 | expect(window.document.addEventListener).toHaveBeenNthCalledWith(1, 'click', () => {});
13
* | ^
14
Thanks in advance.
Advertisement
Answer
I ran this simplified test to check for the side effect (p
element was appended to body):
main.js
JavaScript
1
11
11
1
export default function main() {
2
const createAndAppendPTag = () => {
3
const p = document.createElement('p');
4
document.body.appendChild(p);
5
};
6
7
window.document.addEventListener('click', () => {
8
createAndAppendPTag();
9
});
10
}
11
main.test.js
JavaScript
1
21
21
1
import main from `../main.js`;
2
3
it('"main" listener appends "P" to body upon click', () => {
4
// add listener
5
main();
6
7
// clear body contents
8
document.body.innerHTML = "";
9
10
// dispatch click event to listener
11
const addEvt = new Event('click');
12
document.dispatchEvent(addEvt);
13
14
// check for existence of "P" element
15
const bodyEl = document.body.firstChild;
16
expect(bodyEl).not.toEqual(null);
17
expect(bodyEl.tagName).toBe('P');
18
document.body.innerHTML = "";
19
});
20
21
It passed:
JavaScript
1
2
1
✓ "main" listener appends "P" to body upon click (2 ms)
2