Book Finder项目搜索无结果问题排查及代码测试咨询
Book Finder项目故障排查与修复方案
问题概述
点击搜索按钮后无任何响应,测试代码时出现.document not defined错误,故障核心集中在搜索过滤逻辑、事件绑定及测试环境适配三个层面。
核心故障分析
搜索过滤逻辑错误
filterBooks函数中,flattenObjectValuesIntoArray返回的是书籍对象的扁平化值数组(如["书名", "作者", "标签1", ...]),而非原始书籍对象。后续过滤后返回的是这些扁平化数组,导致structureBooksAsHtml接收的不是合法书籍对象,调用structureBookAsHtml时无法读取book.title等属性,最终渲染失败。事件绑定冗余传参
搜索按钮的事件监听中,不必要地向searchBtnClickHandler传递books参数,但该函数并未定义形参;且函数内部已依赖全局books变量,额外传参属于冗余逻辑。测试环境无DOM对象
测试文件在Node.js环境运行时,helper.js中的structureBookAsHtml使用了浏览器专属的document对象,Node环境未提供该对象,因此抛出.document not defined错误。
修复后的完整代码
核心逻辑代码(script.js)
// 获取搜索框输入值并转为小写 const captureSearchValue = () => { return document.getElementById("search-bar").value.toLowerCase(); }; // 根据搜索词过滤书籍(返回原始书籍对象) const filterBooks = (searchValue, books) => { if (!searchValue) return books; // 空输入返回全部书籍 return books.filter(book => { // 将书籍的所有值扁平化并转为小写,检查是否包含搜索词 const flattenedValues = Object.values(book).flat().map(item => item.toLowerCase()); return flattenedValues.includes(searchValue); }); }; // 将书籍列表转为HTML元素数组 const structureBooksAsHtml = (books) => { return books.map((book) => structureBookAsHtml(book)); }; // 搜索按钮点击处理函数 const searchBtnClickHandler = () => { const searchValue = captureSearchValue(); const filteredBooks = filterBooks(searchValue, books); const structuredBooks = structureBooksAsHtml(filteredBooks); renderBooksToDom(structuredBooks); }; // 绑定搜索按钮事件 const searchBtn = document.getElementById("search-btn"); searchBtn.addEventListener("click", searchBtnClickHandler);
辅助函数调整说明(helper.js)
保留原结构,新增纯逻辑抽离函数便于测试:
// 抽离扁平化书籍值的纯逻辑函数(仅用于测试或复用) const flattenBookValues = (book) => { return Object.values(book).flat().map(item => item.toLowerCase()); }; // 生成单本书籍的HTML元素 const structureBookAsHtml = (book) => { const bookDiv = document.createElement("div"); bookDiv.setAttribute('class', 'bookDiv'); const bookTitle = document.createElement("h2"); bookTitle.innerHTML = book.title; bookTitle.setAttribute('class', 'bookTitle'); const bookAuthor = document.createElement("h3"); bookAuthor.innerHTML = book.author; const bookTags = document.createElement("p"); bookTags.innerHTML = book.tags.join(", "); bookDiv.append(bookTitle, bookAuthor, bookTags); return bookDiv; }; // 渲染书籍到DOM const renderBooksToDom = (elements) => { const bookListContainer = document.querySelector("#bookList"); bookListContainer.innerHTML = ""; bookListContainer.append(...elements); };
测试方案
1. 浏览器端功能测试
- 基础搜索测试:输入存在的标签(如
fiction)、作者名(如N. K. Jemisin)或书名(如1984),点击搜索,验证是否正确渲染对应书籍。 - 空输入测试:清空搜索框后点击搜索,验证是否渲染全部书籍。
- 大小写不敏感测试:输入
FICTION(大写),验证是否与小写搜索结果一致。 - 无匹配测试:输入不存在的内容(如
abc123),验证书籍列表是否清空。
2. 测试环境适配(解决.document not defined错误)
- 使用
jsdom模拟浏览器DOM环境,在测试文件中添加如下配置:
const { JSDOM } = require('jsdom'); const dom = new JSDOM('<!DOCTYPE html><div id="bookList"></div>'); global.document = dom.window.document; global.window = dom.window; // 之后导入并测试纯逻辑函数(如filterBooks、flattenBookValues)
- 分离纯逻辑与DOM操作:将
filterBooks、flattenBookValues等不依赖DOM的函数单独抽离,仅测试这些纯逻辑函数;DOM相关函数可在浏览器端手动测试或使用E2E测试工具(如Cypress)。
内容的提问来源于stack exchange,提问作者jdevries90
相关产品推荐
相关产品推荐

