DOM 挂载方法中的修改不在 JEST 快照中
DOM modification in mounted method not in JEST snapshot
我有一个 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
元素的所有属性都设置正确(宽度、高度、viewBox、样式)。但是 g.chart
元素不包含任何属性(它应该包含 transform
)。 mounted 方法之后使用 D3 语法创建了一堆其他元素(我没有在此处粘贴它们)...none 其中的内容进入快照。
所以我的问题是 this.svg = this.el.select('svg')...
中发生了什么导致无法正确创建快照,我该如何解决这个问题。
我试过nextTick
、jest.useFakeTimers()
、shallow
安装,没有任何东西给我想要的。
谢谢
我做了几件事来解决这个问题:
1) 不再使用 d3.select.attr
修改已安装的 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
方法会有所帮助。
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
我有一个 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
元素的所有属性都设置正确(宽度、高度、viewBox、样式)。但是 g.chart
元素不包含任何属性(它应该包含 transform
)。 mounted 方法之后使用 D3 语法创建了一堆其他元素(我没有在此处粘贴它们)...none 其中的内容进入快照。
所以我的问题是 this.svg = this.el.select('svg')...
中发生了什么导致无法正确创建快照,我该如何解决这个问题。
我试过nextTick
、jest.useFakeTimers()
、shallow
安装,没有任何东西给我想要的。
谢谢
我做了几件事来解决这个问题:
1) 不再使用 d3.select.attr
修改已安装的 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
方法会有所帮助。
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