单元测试中dom-if子元素未被求值的问题排查
解决Polymer dom-if在单元测试中未求值的问题
这种情况我之前在Polymer 1.x和2.x的单元测试里都踩过坑,大概率是数据绑定更新机制没触发或者测试里没等Polymer完成DOM更新周期导致的,给你几个排查和解决的方向:
1. 别直接赋值属性,用Polymer的set方法更新
Polymer的响应式属性依赖内部的变更通知机制,如果你直接写:
element.showContent = true;
这种赋值方式不会触发dom-if的重新求值——因为Polymer没检测到属性变化。正确的做法是用Polymer提供的set方法:
element.set('showContent', true);
这个方法会触发属性变更的观察者,进而让dom-if重新判断是否渲染内容。
2. 确保等待Polymer完成DOM更新
即使调用了Polymer.dom.flush(),有时候DOM更新还需要等一轮微任务或者动画帧。比如在Mocha测试里,你可以用async/await配合requestAnimationFrame来等待:
it('should render hello world when showContent is true', async () => { const element = fixture('your-element-fixture'); // 用set方法更新属性 element.set('showContent', true); // 强制触发同步更新 Polymer.dom.flush(); // 等一轮动画帧确保DOM渲染完成 await new Promise(resolve => requestAnimationFrame(resolve)); // 现在再查询DOM const content = element.shadowRoot.querySelector('p'); expect(content).to.not.be.null; expect(content.textContent).to.equal('hello world'); });
如果不用async/await,也可以用setTimeout配合done回调:
it('should render hello world when showContent is true', (done) => { const element = fixture('your-element-fixture'); element.set('showContent', true); Polymer.dom.flush(); setTimeout(() => { const content = element.shadowRoot.querySelector('p'); expect(content).to.exist; done(); }, 0); });
3. 检查dom-if的依赖和元素定义
- 确保你的元素已经正确导入了dom-if组件:
<link rel="import" href="polymer/lib/elements/dom-if.html">
- 确认dom-if是写在Polymer元素的模板内部,而不是外部的普通HTML里——dom-if是Polymer的专用模板,只能在Polymer元素的作用域里生效。
4. 检查fixture的初始化方式
如果用了test-fixture,别在模板里直接写show-content="true"就完事,有时候fixture初始化时属性绑定可能没生效,最好在测试代码里动态设置属性,确保触发更新。
我之前遇到的类似问题,大多是直接赋值属性没用到set方法,或者没等DOM更新完成就查询元素,按上面的方法调整后基本都解决了。
内容的提问来源于stack exchange,提问作者Vincent
相关产品推荐
相关产品推荐

