Hello I am Clark! Today we're gonna write test case of unit testing for DOM manipulation.
If we have a piece code of HTML and JavaScript in one index.html
file, this is a todo list:
<html>
<body>
<input id="newTodo" />
<button onclick="addTodo()">Add todo</button>
<ol id="todoList"></ol>
<script>
const addTodo = () => {
const newTodoInput = document.getElementById('newTodo');
let currentTodoList = document.getElementById('todoList').innerHTML;
currentTodoList += `<li>${newTodoInput.value}</li>`;
document.getElementById('todoList').innerHTML = currentTodoList;
newTodoInput.value = '';
}
</script>
</body>
</html>
Umm...this todo list give people quite don't know how to write test case, because this code confuse DOM with logic of JavaScript, so first of all, we should would logic of control todo list disassemble from index.html
:
<html>
<body>
<input id="newTodo" />
<button id="addTodo">Add todo</button>
<ol id="todoList"></ol>
<script type="text/javascript" src="./todolist.js"></script>
</body>
</html>
About logic of todo list move to todoList.js
file:
const addTodo = () => {
const newTodoInput = document.getElementById('newTodo');
let currentTodoList = document.getElementById('todoList').innerHTML;
currentTodoList += `<li>${newTodoInput.value}</li>`;
document.getElementById('todoList').innerHTML = currentTodoList;
newTodoInput.value = '';
}
document.getElementById('addTodo').addEventListener('click', addTodo);
Right now, view is view, logic is logic, so we can very easy to write test case for JavaScript, but...we no have DOM, how to trigger addTodo
? yes! so we must ready DOM for test case of addTodo
!
As mention document of Jest:
Jest ships with jsdom which simulates a DOM environment as if you were in the browser. This means that every DOM API that we call can be observed in the same way it would be observed in a browser!
So we can very easy to simulates a DOM environment when use Jest, get start install Jest and write test case!
Install Jest in project(If you have no npm or NodeJS environment, must download Node when before start):
npm install jest
Next, we add file todoList.test.js
and write a test case:
test('Check addTodo able add todo to todoList', () => {
});
Like above name of test case, I want test function addTodo
can be real add todo to todoList.
I’ve divided write test case into three parts:
-
We have to find out which elements is
addTodo
need? let's look attodoList.js
,first we need abutton
of id isaddTodo
, we will would add click event ofaddTodo
for it, also need ainput
of id isnewTodo
, last we need aol
of id istodoList
to display todo list.Yes! just three elements is
addTodo
need! we don't care other elements in the HTML file, we just only prepare those for test case:
test('Check addTodo able add todo to todoList', () => {
document.body.innerHTML = `
<input id="newTodoInput" />
<button id="addTodoBtn">Add todo</button>
<ol id="todoList"></ol>
`;
});
- Use
require
importtodoList.js
file add logic to elements of readied, it have logic ofaddTodo
, it is we target of test in test case too:
test('Check addTodo able add todo to todoList', () => {
document.body.innerHTML = `
<input id="newTodoInput" />
<button id="addTodoBtn">Add todo</button>
<ol id="todoList"></ol>
`;
require('../todolist.js');
});
- Use selector get element, write new todo name
input
and triggeraddTodo
bybutton
, then check ifinnerHTML
ofol
correct add new todo!
test('Check addTodo able add todo to todoList', () => {
document.body.innerHTML = `
<input id="newTodoInput" />
<button id="addTodoBtn">Add todo</button>
<ol id="todoList"></ol>
`;
require('../todolist.js');
const newTodoInput = document.getElementById('newTodoInput');
const addTodoBtn = document.getElementById('addTodoBtn');
const todolist = document.getElementById('todoList');
newTodoInput.value = 'New todolist!';
addTodoBtn.click();
expect(todolist.innerHTML).toBe('<li>New todolist!</li>');
});
Now we're finish first test case for todoList.js
! let's execute test check if logic correct:
Thanks guys for reading this post, if you have any question or find out ant wrong in the post, please submit discussion for me! 😃
On the other hand, this post simultaneous publish to my blog: Jest | Use Jest write unit testing for DOM manipulation
Top comments (10)
We have a typo on
npm install jest
is there any way to unit test the following? addTodo is not found.
document.body.innerHTML =
;<input id="newTodoInput" />
<button id="addTodoBtn" onclick="addTodo()">Add todo</button>
<ol id="todoList"></ol>
I wrote this:
test('Check addTodo able add todo to todoList', () => {
document.body.innerHTML =
;<input id="newTodoInput" />
<button id="addTodoBtn">Add todo</button>
<ol id="todoList"></ol>
const newTodoInput = document.getElementById('newTodoInput');
const addTodoBtn = document.getElementById('addTodoBtn');
addTodoBtn.addEventListener('click', addTodo);
const todolist = document.getElementById('todoList');
newTodoInput.value = 'New todolist!';
addTodoBtn.click();
expect(todolist.innerHTML).toBe('<li>New todolist!</li>');
});
which does work.
Good read actually.
Thank you for you read this article!
Check the "newTodo" and "addToDo" ID. It's not the same with the test file.
Btw, thank you for this.
You just saved my life <3
I tried added style to this innerHtml doesnt work.
Thank you for this post, you save my life pal, blessings
When we access document object inside a test, what exactly is that? When we do an appendElement or whichever DOM API, what happens? Is it a virtual DOM?
Some comments may only be visible to logged-in visitors. Sign in to view all comments.