挂载方法中的 DOM 修改不在 JEST 快照中
Posted
技术标签:
【中文标题】挂载方法中的 DOM 修改不在 JEST 快照中【英文标题】:DOM modification in mounted method not in JEST snapshot 【发布时间】:2018-07-12 23:16:16 【问题描述】:我有一个 Vue 组件,在 mounted
方法中我有这个:
this.el = d3.select(this.$el);
this.svg = this.el.select('svg')
.attr('width', mainSvgPos.svgWidth)
.attr('height', mainSvgPos.svgHeight)
.attr('viewBox', "0 0 " + mainSvgPos.svgWidth + " " + mainSvgPos.svgHeight)
.attr('style',"position:absolute;left:0;top:20px;width:100%;height:100%")
this.chart = this.svg.select('g.chart').attr('transform', "translate(" + chartCenter.leftOffset + ", " + chartCenter.topOffset + ")")
我正在使用jest
和vue-test-util
测试这个组件
我的测试是这样的:
describe('gauge', () =>
const wrapper = shallow(gauge,
propsData: ...some data,
)
it('renders correctly', () =>
expect(wrapper.vm.$el).toMatchSnapshot()
);
)
当它第一次运行时,正如预期的那样,它会创建快照。在此快照中,我的父 svg
元素具有正确设置的所有属性(宽度、高度、视图框、样式)。但是g.chart
元素不包含任何属性(它应该包含transform
)。之后,mounted 方法使用 D3 语法创建了一堆其他元素(我没有在这里粘贴它们)......这些都没有进入快照。
所以我的问题是this.svg = this.el.select('svg')...
中发生了什么会阻止正确创建快照以及如何解决这个问题。
我已经尝试过nextTick
、jest.useFakeTimers()
、shallow
安装,但没有什么能满足我的需求。
谢谢
【问题讨论】:
【参考方案1】:test('the d3 svg chart renders with the component', () =>
const wrapper = mount(D3Chart,
attachToDocument: true,
);
expect(wrapper.html()).to.contain('svg');
wrapper.destroy();
);
在https://github.com/vuejs/vue-test-utils/issues/369 中找到的帮助了我。我不得不添加 最后的 wrapper.destroy() 以从文档中删除呈现的元素并销毁组件实例。 https://vue-test-utils.vuejs.org/api/options.html#attachtodocument
【讨论】:
【参考方案2】:我做了几件事来解决这个问题:
1) 不再使用d3.select.attr
修改mounted 中的svg
和g.chart
属性。我通过 props 修改了这些属性
2) 在原代码中,这一行之后:
this.chart = this.svg.select('g.chart').attr('transform', "translate(" + chartCenter.leftOffset + ", " + chartCenter.topOffset + ")")
我通过 d3 生成了渐变弧:
const arc = d3.arc()
.innerRadius(this.arc_radius - this.chart_inset - this.bar_width)
.outerRadius(this.arc_radius - this.chart_inset)
.startAngle(function (d)
return d.startAngle;
).endAngle(function (d)
return d.endAngle;
);
d3.select(this.$el).append('g').selectAll('path').data(this.pieces).enter()
.append('path').attr("d", arc)
.attr("stroke-width", 1).attr("stroke", function (d)
return d.fill;
).attr("fill", function (d)
return d.fill;
);
这也没有进入快照。即使在完成上述第 1 点之后。我将这个渐变弧生成移动到一个新组件的mounted
方法中。突然它开始工作了。新组件上的shallow
正确创建了标记。请注意,在新组件中,我仍然使用d3.selectAll
...但这次它按预期工作
所以这并不能回答上一个问题,但也许重构组件的 mounted
方法会有所帮助。
【讨论】:
以上是关于挂载方法中的 DOM 修改不在 JEST 快照中的主要内容,如果未能解决你的问题,请参考以下文章
快照测试的工作原理以及 toMatchSnapshot() 函数在 React 组件的 Jest 快照测试中的作用是啥?
jest 快照测试:如何在 jest 测试结果中忽略部分快照文件
java中在构造方法中修改线程名,修改失败原因(现已修改成功)