I want to test this FooComponent:

  <slot :fn="internalFn" />

It's used like that (ParentComponent):

  <template slot-scope="slotProps">
    <BarComponent @some-event="slotProps.fn" />

So I want to test how my component reacts on calling this "fn" from slot props. The easiest way I see is to take method itself and call it, like that:

cosnt wrapper = shallowMount(FooComponent, /* ... */)
wrapper.vm.methods.internalFn(/* test payload */)
expect(wrapper.emitted()).toBe(/* some expectation */)

But this is well known as anti-pattern about testing internal implementation. So instead I would like to test it via prop fn passed into slot, because it's also some sort of component interface, like component own props.

But how to to test props passed in slot? I can imagine it's working only in case if I test that ParentComponent something like that:

const wrapper = shallowMount(ParentComponent, /* ... */)
const foo = wrapper.find(FooComponent)
wrapper.find(BarComponent).vm.$emit('some-event', /*...*/)
/* write expectations against foo */

But that feels like tests for FooComponent inside tests for ParentComponent

Maybe there is a better way to do it?


Since there is no answers so I just share what I ended up with.

I decided to test internal method. It's not cool, but at least, because I use typescript, I have a type-safe test, which will fail with clear type error if I rename or modify method which I test. Looks like this:

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 */)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.