Description
What problem does this feature solve?
Given the following component:
export default {
{
data() {
return {
count: 0
};
},
methods: {
increment() {
this.count++;
}
},
render() {
return this.$scopedSlots.default({
increment: this.increment // <-- api given to scoped slot
});
}
}
}
How should the API given to scoped slots be tested?
Currently, the best approach I've found is creating a test helper component that's mounted in the test and renders the given component and it's scoped slot contents. Example of this approach by posva: https://github.com/posva/vue-promised/tree/master/test/utils
Creating a component to be used just for unit tests in not ideal. It's extra code polluting my tests folder. That code can be complicated and the more complex the component api the more components are needed to fully test the api.
What does the proposed API look like?
The solution to this could be to expose the scoped slot api from wrapper.
const wrapper = shallowMount(MyComponent);
expect(wrapper.vm.count).toBe(0);
wrapper.scopedSlotApi().default.increment(); // <-- using scoped slots api
expect(wrapper.vm.count).toBe(1);
This provides several benefits.
- I can simple assert that the api exposes the correct methods. Currently there's no way to do this with methods. I actually have to render scoped slot content that ties some event to the method, trigger the event and then assert the method made some change.
- The test is concerned with testing the api and doesn't have to build out a rendering of the API to test that.
Alternate solution
Maybe this would be a better approach as it doesn't add any new methods to wrapper api.
The mount options for scopedSlots could be given the api which could then be captured.
let capturedApi;
const wrapper = mount(MyComponent, {
scopedSlots: {
default: api => {
capturedApi = api;
}
}
});
expect(capturedApi.increment).toBeDefined();
expect(wrapper.vm.count).toBe(0);
capturedApi.increment();
expect(wrapper.vm.count).toBe(1);