【发布时间】:2020-08-19 20:32:20
【问题描述】:
我有一个 Vue.js 组件,它显示一个 BootstrapVue 横幅以响应提交错误。在手动测试期间一切正常,但相应的单元测试失败。
错误如下。
[vue-test-utils]: find did not return #submit-failure-banner, cannot call isVisible() on empty Wrapper
36 |
37 | const errorBanner = wrapper.find("#submit-failure-banner")
> 38 | expect(errorBanner.isVisible()).toBeTruthy()
| ^
39 | })
40 | })
41 |
it("shows an error message on post failure", async () => {
const wrapper = mount(NewSite, {
localVue,
provide: {
sites: new Sites(internalServerErrorRequestHandler)
}
});
const siteOwnerInput = wrapper.find('#new-site-owner-input');
siteOwnerInput.setValue(owner);
const saveButton = wrapper.find('#new-site-save');
saveButton.trigger('click');
await wrapper.vm.$nextTick();
const errorBanner = wrapper.find("#submit-failure-banner")
expect(errorBanner.isVisible()).toBeTruthy()
})
NewSite 组件的相关部分如下,从模板中的横幅元素开始。
<b-alert id="submit-failure-banner" variant="danger" v-model="banners.submitFailure" dismissible>
{{ $t('$MESSAGE_SITE_SAVE_FAILED') }}
</b-alert>
export default class NewSite extends Vue {
@Inject('sites') private sites!: Sites
form = {
owner: ''
}
banners = {
submitFailure: false,
...
}
async postForm() {
return await this.sites.create({
owner: this.form.owner,
state: SiteStatus.NEW
}).save()
}
...
async onSave() {
if (!this.checkForm()) {
return;
}
try {
await this.postForm();
await this.$router.push({name: 'dashboard'})
} catch (_) {
this.banners.submitFailure = true;
}
}
Sites 类的相关部分只不过是使用请求处理程序的 POST 请求。这是生产中的axios,以及测试期间的模拟请求处理程序。 internalServerErrorRequestHandler 是这样定义的。
const internalServerErrorRequestHandler = {
post(url: string, data: any): Promise<Response> {
return Promise.reject()
}
}
我通过console.log 声明验证了 html 不显示横幅。
【问题讨论】:
-
我认为您需要在触发点击后添加一个额外的
await wrapper.vm.$nextTick();,以便 Vue 有时间处理点击处理程序和<transition>(这是<b-alert>的根)。 -
我尝试添加一个额外的
await wrapper.vm.$nextTick();并像here 描述的那样存根transition。都没有解决问题。 -
其实你可能需要挂载选项
attachToFocument: true,用documentQuerySelector('#submit-failure-banner')代替wrapper.find('#submit-failure-banner'),检查元素是div而不是isVisible。 -
或者,在您的 await nextTick 之后,添加
await new Promise(resolve => requestAnimationFrame(resolve)),这将为触发未存根的转换留出时间。
标签: typescript vue.js bootstrap-vue vue-test-utils