如何在Jest中正确Mock noUiSlider.set解决单元测试报错
解决noUiSlider.set单元测试Mock问题
我来帮你搞定这个单元测试报错的问题!你遇到的TypeError: Cannot read property 'set' of undefined,核心原因是你的Mock方案没有把noUiSlider挂到正确的位置——noUiSlider插件初始化后,是作为目标DOM元素的属性存在的,而不是挂在window或document上。之前的两种Mock方式都没命中正确的挂载点,所以调用element.noUiSlider.set时才会找不到方法。
正确的Mock方案
根据你的代码逻辑,element是self.isRangeElement(name).element返回的DOM元素,我们需要给这个具体的DOM元素添加noUiSlider属性,并Mock它的set方法。
方案1:直接给目标元素Mock noUiSlider
在你的测试用例中,先获取到滑块元素,然后给它手动添加noUiSlider对象:
test('should set range state', () => { // 渲染滑块DOM document.body.innerHTML = `<div id="twobuttons-range_0" class="twobuttons-range" data-technicalname="motor" data-unit="mm" data-min="100" data-max="500" data-start="[30,50]"></div>`; // 获取目标滑块元素 const sliderElement = document.getElementById('twobuttons-range_0'); // Mock noUiSlider及其set方法 sliderElement.noUiSlider = { set: jest.fn() }; // 确保测试所需的其他变量(比如rangeSlider、name)已正确赋值 window.rangeSlider = true; window.name = 'motor'; // 匹配元素的data-technicalname // 执行测试函数 popState(); // 验证元素存在,同时可以验证set方法是否被调用 expect($('#twobuttons-range_0').length).toBe(1); expect(sliderElement.noUiSlider.set).toHaveBeenCalled(); });
方案2:全局Mock DOM元素的原型(适合多个测试用例)
如果你的测试中有多个滑块需要Mock,可以给HTMLElement原型添加noUiSlider,这样所有DOM元素都会继承这个属性:
// 在测试文件的beforeEach钩子中全局Mock beforeEach(() => { // 给所有DOM元素添加Mock的noUiSlider Object.defineProperty(HTMLElement.prototype, 'noUiSlider', { value: { set: jest.fn() }, writable: true }); }); test('should set range state', () => { document.body.innerHTML = `<div id="twobuttons-range_0" class="twobuttons-range" data-technicalname="motor" data-unit="mm" data-min="100" data-max="500" data-start="[30,50]"></div>`; window.rangeSlider = true; window.name = 'motor'; popState(); expect($('#twobuttons-range_0').length).toBe(1); // 验证set方法调用 expect(document.getElementById('twobuttons-range_0').noUiSlider.set).toHaveBeenCalled(); });
为什么之前的方案无效?
- 方案1:你把
noUiSlider挂在了dom对象上,但实际代码中是操作具体的滑块DOM元素,两者不是同一个对象,所以element.noUiSlider仍然是undefined。 - 方案2:你给
document添加了noUiSlider属性,但document并不是你的滑块元素,自然无法命中目标。
内容的提问来源于stack exchange,提问作者Kwaadjei
相关产品推荐
相关产品推荐

