You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Book Finder项目搜索无结果问题排查及代码测试咨询

Book Finder项目故障排查与修复方案

问题概述

点击搜索按钮后无任何响应,测试代码时出现.document not defined错误,故障核心集中在搜索过滤逻辑、事件绑定及测试环境适配三个层面。

核心故障分析

  1. 搜索过滤逻辑错误
    filterBooks函数中,flattenObjectValuesIntoArray返回的是书籍对象的扁平化值数组(如["书名", "作者", "标签1", ...]),而非原始书籍对象。后续过滤后返回的是这些扁平化数组,导致structureBooksAsHtml接收的不是合法书籍对象,调用structureBookAsHtml时无法读取book.title等属性,最终渲染失败。

  2. 事件绑定冗余传参
    搜索按钮的事件监听中,不必要地向searchBtnClickHandler传递books参数,但该函数并未定义形参;且函数内部已依赖全局books变量,额外传参属于冗余逻辑。

  3. 测试环境无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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.28 20:39:58