DOM Manipulation
Another class of functions that is often considered difficult to test is code that directly manipulates the DOM. Let's see how we can test the following snippet of jQuery code that listens to a click event, fetches some data asynchronously and sets the content of a span.
// displayUser.js
'use strict';
const $ = require('jquery');
const fetchCurrentUser = require('./fetchCurrentUser.js');
$('#button').click(() => {
fetchCurrentUser(user => {
const loggedText = 'Logged ' + (user.loggedIn ? 'In' : 'Out');
$('#username').text(user.fullName + ' - ' + loggedText);
});
});
Novamente, nós criamos um arquivo de teste na pasta __tests__/
:
// __tests__/displayUser-test.js
'use strict';
jest.mock('../fetchCurrentUser');
test('displays a user after a click', () => {
// Set up our document body
document.body.innerHTML =
'<div>' +
' <span id="username" />' +
' <button id="button" />' +
'</div>';
// This module has a side-effect
require('../displayUser');
const $ = require('jquery');
const fetchCurrentUser = require('../fetchCurrentUser');
// Tell the fetchCurrentUser mock function to automatically invoke
// its callback with some data
fetchCurrentUser.mockImplementation(cb => {
cb({
fullName: 'Johnny Cash',
loggedIn: true,
});
});
// Use jquery to emulate a click on our button
$('#button').click();
// Assert that the fetchCurrentUser function was called, and that the
// #username span's inner text was updated as we'd expect it to.
expect(fetchCurrentUser).toBeCalled();
expect($('#username').text()).toEqual('Johnny Cash - Logged In');
});
The function being tested adds an event listener on the #button
DOM element, so we need to set up our DOM correctly for the test. 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!
Nós estão simulamos fetchCurrentUser.js
para que nosso teste não faça uma solicitação de rede real, mas em vez disso resolve os dados da simulação localmente. Isso garante que nosso teste pode ser concluído em milissegundos, em vez de segundos e garante uma rápida iteração de teste unitário.
O código deste exemplo está disponível em examples/jquery.