如何在Jest中触发带选择器的jQuery回调函数?
问题分析与解决办法
1. 先修复原JS脚本的bug
你的MainPage模块里,return { page: pageFunction() }是直接执行了pageFunction,把执行结果(实际是undefined,因为这个函数没有返回值)赋值给了page属性。测试里调用MainPage.page()肯定报错,因为MainPage.page根本不是函数。
修正后的脚本:
function MainPage(){ function pageFunction(){ $(".page").on("shown.bs.collapse, hidden.bs.collapse", '.module.content', function (e) { // 加个日志方便测试查看触发情况 console.log('回调触发了'); }); } // 返回函数引用,而非执行结果 return { page: pageFunction } } module.exports = MainPage;
2. HTML结构需要调整
你的事件绑定在.page下的.module.content上,监听Bootstrap的collapse事件,但当前HTML里,.module.content和collapse元素是同级关系——Bootstrap的collapse事件只会在带.collapse的组件元素或其触发按钮上触发,不会自动传递到无关的.module.content元素上。
如果需求是collapse切换时触发.module.content的回调,要么把.module.content设为collapse的内容区,要么调整事件绑定逻辑。比如改成符合Bootstrap collapse标准结构的HTML:
<div class="page"> <!-- collapse触发按钮 --> <button type="button" data-bs-toggle="collapse" data-bs-target="#collapseBox"> 点我切换折叠内容 </button> <!-- collapse容器 --> <div class="collapse" id="collapseBox"> <div class="card card-body"> Test </div> </div> <!-- 你的模块内容 --> <div class='module'> <div class='header'></div> <div class='content'></div> </div> </div>
3. Jest测试代码修正
测试需要注意这几点:
- 先实例化
MainPage,再调用page()绑定事件 - 手动触发对应的collapse事件,或触发collapse切换来触发事件
- 用Jest的模拟函数验证回调是否被触发
修正后的测试代码:
const $ = require('jquery'); const MainPage = require('./mainpage'); beforeEach(() => { // 每次测试前清空body,避免残留内容影响结果 $('body').empty(); const htmlcontent = ` <div class="page"> <button type="button" data-bs-toggle="collapse" data-bs-target="#collapseBox"> 点我切换折叠内容 </button> <div class="collapse" id="collapseBox"> <div class="card card-body"> Test </div> </div> <div class='module'> <div class='header'></div> <div class='content'></div> </div> </div> `; $('body').html(htmlcontent); }); describe("test cases mainpage", () => { test("testing function call", () => { // 实例化并绑定事件 const mainPage = MainPage(); mainPage.page(); // 创建模拟函数,用于检测是否被调用 const mockCallback = jest.fn(); // 给目标元素绑定该模拟回调 $(".page .module.content").on("shown.bs.collapse", mockCallback); // 手动触发事件 $(".page .module.content").trigger("shown.bs.collapse"); // 断言模拟函数被调用了一次 expect(mockCallback).toHaveBeenCalledTimes(1); }); });
额外提醒
如果你的需求是collapse组件切换时,触发.module.content的逻辑,原事件绑定的写法并不合理——.page上监听事件委托给.module.content,但collapse事件是在collapse元素上触发的,不会冒泡到.module.content。正确的写法应该是监听collapse元素的事件,再处理.module.content:
$(".page .collapse").on("shown.bs.collapse, hidden.bs.collapse", function (e) { // 这里写你要对.module.content执行的操作 $(".page .module.content").addClass('active'); });
内容的提问来源于stack exchange,提问作者keerthi
相关产品推荐
相关产品推荐

