首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何用插槽和插槽道具测试组件

如何用插槽和插槽道具测试组件
EN

Stack Overflow用户
提问于 2019-06-07 10:14:22
回答 2查看 10.6K关注 0票数 12

我想测试这个FooComponent

代码语言:javascript
复制
<div>
  <slot :fn="internalFn" />
</div>

它是这样使用的(例如在ParentComponent中):

代码语言:javascript
复制
<FooComponent>
  <template slot-scope="slotProps">
    <BarComponent @some-event="slotProps.fn" />
  </template>
</FooComponent>

因此,我想测试我的组件在从插槽道具中调用这个"fn“时是如何反应的。我看到的最简单的方法就是采用方法本身并调用它,就像这样:

代码语言:javascript
复制
cosnt wrapper = shallowMount(FooComponent, /* ... */)
wrapper.vm.methods.internalFn(/* test payload */)
expect(wrapper.emitted()).toBe(/* some expectation */)

但是这是众所周知的关于测试内部实现的反模式。因此,我想通过传递到插槽的fn来测试它,因为它也是某种组件接口,比如组件自己的道具。

但是如何测试插槽中的道具?我可以想象,只有在测试类似于ParentComponent的情况下,它才能起作用:

代码语言:javascript
复制
const wrapper = shallowMount(ParentComponent, /* ... */)
const foo = wrapper.find(FooComponent)
wrapper.find(BarComponent).vm.$emit('some-event', /*...*/)
/* write expectations against foo */

但这感觉就像FooComponent内部的ParentComponent测试

也许有更好的方法来做这件事?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2019-06-12 21:24:41

UPD:线下的是我几年前给出的最初答案。因为今天我要说,其中一种方法就足够好了:

  1. 不要测试插槽方法,而是测试依赖于它的面向用户的特性。首先尝试手动测试它,注意您是如何做到的,然后尝试编写一个类似的测试。例如用测试-库/vue
  2. 如果第一个选项太难做,试着想出一些假的测试组件。这个想法与我在问题中所描述的非常相似。

但这感觉就像FooComponent内部的ParentComponent测试

但是,不是使用ParentComponent,而是创建一些非常简单的内联组件(就在您的FooComponent.spec.js文件中),它使用带有插槽的组件。

最初的答复是在2020年提出的:

因为没有答案,所以我只跟大家分享我的结局。

我决定测试内部方法。这不是很酷,但至少,因为我使用类型记录,我有一个类型安全的测试,如果我重命名或修改测试的方法,就会出现明显的类型错误。看起来是这样的:

代码语言:javascript
复制
import Foo from '@/components/foo/Foo.ts'
import FooComponent from '@/components/foo/Foo.vue'

/*...*/

cosnt wrapper = <Foo>shallowMount(FooComponent, /* ... */)

// notice that because I passed `Foo` which is a class-component, 
// I have autocomplete and type checks for vm.*
wrapper.vm.internalFn(/* test payload */)

expect(wrapper.emitted()).toBe(/* some expectation */)
票数 1
EN

Stack Overflow用户

发布于 2019-12-10 01:26:24

我参加聚会有点晚了,但我也遇到了同样的问题。我从实际的Vue测试中获得了一些提示,虽然与我们相比,它们在测试内容上更抽象,但确实有帮助。

我想出的是:

代码语言:javascript
复制
import { shallowMount } from '@vue/test-utils';
import Component from 'xyz/Component';

let wrapperSlotted;

describe('xyz/Component.vue', () => {
  beforeAll(() => {
    wrapperSlotted = shallowMount(Component, {
      data() {
        return { myProp: 'small' }
      },
      scopedSlots: {
        default: function (props) {
          return this.$createElement('div', [props.myProp]);
        }
      },
    });
  });

  it('slot prop passed to a scoped slot', () => {
    let text = wrapperSlotted.find('div').text();
    expect(text).toBe('small'); // the value of `myProp`, which has been set as the text node in the slotted <div />
  });
});

因此,最主要的是,我使用了scopedSlots的呈现函数。

希望对某人有帮助:)

票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/56492371

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档