如何用Karma/Jasmine为简单jQuery代码编写单元测试?
解决jQuery "Hello, world!" 单元测试问题
嘿,我来帮你搞定这个jQuery单元测试的难题!你之前的测试没成功,核心原因有两个:一是测试环境里默认没有#message这个DOM元素,jQuery根本找不到目标元素;二是你监视的是jQuery原型的text方法,而不是实际选中目标元素后的那个jQuery实例的方法。下面给你两种可行的解决方案:
方案一:直接验证DOM文本内容(最直观)
这种方法最贴近用户实际看到的效果,直接检查目标元素的文本是否符合预期。因为测试环境是干净的,所以首先要手动创建#message元素:
describe('main', () => { beforeEach(() => { // 每次测试前在DOM中插入目标元素,确保jQuery能选中它 // 如果你用了jasmine-jquery,也可以用`setFixtures('<div id="message"></div>')`,更简洁 document.body.innerHTML = '<div id="message"></div>'; }); it('should set "Hello, world!" text on #message', () => { // 加载你的主模块,触发里面的jQuery代码执行 require('./main'); // 直接断言元素的文本内容 expect($('#message').text()).toBe('Hello, world!'); }); });
方案二:监视特定jQuery实例的text方法
如果你确实需要验证text方法被调用的参数(而不是只看结果),那就要先获取选中#message后的jQuery实例,再监视它的text方法:
describe('main', () => { let $messageElement; beforeEach(() => { // 先创建DOM元素并获取对应的jQuery实例 document.body.innerHTML = '<div id="message"></div>'; $messageElement = $('#message'); // 监视这个特定实例的text方法,保留原方法逻辑(and.callThrough()) spyOn($messageElement, 'text').and.callThrough(); }); it('should call text() with "Hello, world!" on #message', () => { require('./main'); // 断言这个实例的text方法被正确调用 expect($messageElement.text).toHaveBeenCalledWith('Hello, world!'); }); });
为什么你之前的测试失败?
- 缺少DOM元素:测试环境默认没有
#message,$('#message')返回的是空jQuery集合,虽然调用text()不会报错,但实际没有作用到任何元素,你的监视也捕捉不到有效调用。 - 监视对象错误:
jQuery.prototype.text是所有jQuery实例的原型方法,但$('#message')返回的是一个新的实例,你需要监视的是这个具体实例的方法,而不是原型上的方法(除非你想监视所有实例的调用,但这不是你要的场景)。
内容的提问来源于stack exchange,提问作者kshetline
相关产品推荐
相关产品推荐

