Jest DOM操作
另一类通常被认为难以测试的函数是直接操作 DOM 的代码。让我们看看如何测试以下用来侦听单击事件、异步获取一些数据并设置 span 的内容的 jQuery 代码片段。
// 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);});});
接着,我们在__tests__/文件夹下创建一个测试文件:
// __tests__/displayUser-test.js'use strict';jest.mock('../fetchCurrentUser');test('displays a user after a click', () => {// Set up our document bodydocument.body.innerHTML ='<div>' +' <span id="username" />' +' <button id="button" />' +'</div>';// This module has a side-effectrequire('../displayUser');const $ = require('jquery');const fetchCurrentUser = require('../fetchCurrentUser');// Tell the fetchCurrentUser mock function to automatically invoke// its callback with some datafetchCurrentUser.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');});
被测试的函数在#buttonDOM 元素上添加了一个事件监听器,所以我们需要为测试正确设置我们的 DOM。Jest 附带jsdom它模拟 DOM 环境,就像在浏览器中一样。这意味着我们调用的每个 DOM API 都可以像在浏览器中一样被观察到!
我们模拟了 fetchCurrentUser.js的实现,这样我们的测试就不会产生真正的网络请求,而是使用本地mock的数据。 这确保了我们的测试能够在毫秒级完成,而不是秒,并且保证了快速的单元测试迭代速度。
这个例子的代码可以 examples/jquery找到。