test-utils: Bug: _ctx is missing functions that are returned from the setup functions

Hi, I started getting the error below after upgrading from 2.2.1 to 2.2.2.

    Received message:   "_ctx.hasIcon is not a function"

          209 |           props.countryCode.charAt(0).toUpperCase() +
          210 |           props.countryCode.slice(1),
        > 211 |       };
              |                   ^
          212 |     });
          213 |
          214 |     const hasIcon = () => Boolean(slots.icon);

          at src/components/avatar/Avatar.vue:211:139
          at renderFnWithContext (node_modules/@vue/runtime-core/dist/runtime-core.cjs.js:845:19)
          at renderSlot (node_modules/@vue/runtime-core/dist/runtime-core.cjs.js:2996:55)
          at src/components/box/Box.vue:146:59
          at renderFnWithContext (node_modules/@vue/runtime-core/dist/runtime-core.cjs.js:845:19)
          at normalizeChildren (node_modules/@vue/runtime-core/dist/runtime-core.cjs.js:6939:42)
          at createBaseVNode (node_modules/@vue/runtime-core/dist/runtime-core.cjs.js:6688:9)
          at _createVNode (node_modules/@vue/runtime-core/dist/runtime-core.cjs.js:6790:12)
          at createVNodeWithArgsTransform (node_modules/@vue/runtime-core/dist/runtime-core.cjs.js:6645:12)
          at createBlock (node_modules/@vue/runtime-core/dist/runtime-core.cjs.js:6617:23)
          at Proxy.render (src/components/box/Box.vue:142:54)
          at renderComponentRoot (node_modules/@vue/runtime-core/dist/runtime-core.cjs.js:891:44)
          at ReactiveEffect.componentUpdateFn [as fn] (node_modules/@vue/runtime-core/dist/runtime-core.cjs.js:5570:57)
          at ReactiveEffect.run (node_modules/@vue/reactivity/dist/reactivity.cjs.js:191:25)
          at instance.update (node_modules/@vue/runtime-core/dist/runtime-core.cjs.js:5684:56)
          at setupRenderEffect (node_modules/@vue/runtime-core/dist/runtime-core.cjs.js:5698:9)
          at mountComponent (node_modules/@vue/runtime-core/dist/runtime-core.cjs.js:5480:9)
          at processComponent (node_modules/@vue/runtime-core/dist/runtime-core.cjs.js:5438:17)
          at patch (node_modules/@vue/runtime-core/dist/runtime-core.cjs.js:5042:21)
          at ReactiveEffect.componentUpdateFn [as fn] (node_modules/@vue/runtime-core/dist/runtime-core.cjs.js:5577:21)
          at ReactiveEffect.run (node_modules/@vue/reactivity/dist/reactivity.cjs.js:191:25)
          at instance.update (node_modules/@vue/runtime-core/dist/runtime-core.cjs.js:5684:56)
          at setupRenderEffect (node_modules/@vue/runtime-core/dist/runtime-core.cjs.js:5698:9)
          at mountComponent (node_modules/@vue/runtime-core/dist/runtime-core.cjs.js:5480:9)
          at processComponent (node_modules/@vue/runtime-core/dist/runtime-core.cjs.js:5438:17)
          at patch (node_modules/@vue/runtime-core/dist/runtime-core.cjs.js:5042:21)
          at ReactiveEffect.componentUpdateFn [as fn] (node_modules/@vue/runtime-core/dist/runtime-core.cjs.js:5577:21)
          at ReactiveEffect.run (node_modules/@vue/reactivity/dist/reactivity.cjs.js:191:25)
          at instance.update (node_modules/@vue/runtime-core/dist/runtime-core.cjs.js:5684:56)
          at setupRenderEffect (node_modules/@vue/runtime-core/dist/runtime-core.cjs.js:5698:9)
          at mountComponent (node_modules/@vue/runtime-core/dist/runtime-core.cjs.js:5480:9)
          at processComponent (node_modules/@vue/runtime-core/dist/runtime-core.cjs.js:5438:17)
          at patch (node_modules/@vue/runtime-core/dist/runtime-core.cjs.js:5042:21)
          at render (node_modules/@vue/runtime-core/dist/runtime-core.cjs.js:6198:13)
          at mount (node_modules/@vue/runtime-core/dist/runtime-core.cjs.js:4432:25)
          at Object.app.mount (node_modules/@vue/runtime-dom/dist/runtime-dom.cjs.js:1549:23)
          at _mount (node_modules/@vue/test-utils/dist/vue-test-utils.cjs.js:8215:18)
          at createWrapper (src/lib/test-utils.js:19:10)
          at src/components/avatar/Avatar.test.js:170:53
          at Object.<anonymous> (node_modules/expect/build/toThrowMatchers.js:83:11)
          at Object.throwingMatcher [as toThrowError] (node_modules/expect/build/index.js:382:21)
          at testBody (src/components/avatar/Avatar.test.js:174:16)
          at testErrors (src/lib/test-utils.js:87:3)
          at Object.<anonymous> (src/components/avatar/Avatar.test.js:169:35)

      172 |                 slots: { icon: '<div />' },
      173 |               }),
    > 174 |             ),
          |                ^
      175 |           ).toThrowError(ERRORS.ONLY_SVG);
      176 |         });
      177 |       });

      at testBody (src/components/avatar/Avatar.test.js:174:16)
      at testErrors (src/lib/test-utils.js:87:3)
      at Object.<anonymous> (src/components/avatar/Avatar.test.js:169:35)

Describe the bug I do slot validations in the setup function, sometimes to hide certain HTML elements and sometimes for their content. I created a helper to capture the errors.

function testErrors(testBody) {
  /**
   * @see https://github.com/vuejs/vue-test-utils/issues/641#issuecomment-443651405
   * @see https://github.com/vuejs/test-utils/issues/1096
   */
  const spyError = jest
    .spyOn(global.console, 'error')
    .mockImplementation(() => {});

  testBody();

  spyError.mockRestore();
}

I write the tests like this:

it('throws an error', () => {
  testErrors(() => {
    expect(() =>
      // mount component
    ).toThrowError(ERROR_MESSAGE);
  });
});

When I upgraded to 2.2.2 I started getting the error above. It seems the functions that I use in the template are not being populated from the setup function.

I assume the problem that Iā€™m having is related to this change https://github.com/vuejs/test-utils/commit/74c9af4e35430fb0c3b5cd7366d349b1a8160fd9

To Reproduce

<template>
  <div v-if="hasSlot('test')">
    <slot name="test"></slot>
  </div>
  <slot></slot>
</template>

<script>
export default {
  setup(_, { slots }) {
    const hasSlot = (slotName) => Boolean(slots[slotName]);

    if (!hasSlot('default')) throw new Error('The default slot is required');
    
    return { hasSlot }
  }
}
</script>

Expected behavior

The component should be able to use the functions that are returned from the setup function.

Related information:

  • @vue/test-utils version: 2.2.2
  • Vue version: 3.2.45
  • node version: 16.17.0
  • npm (or yarn) version: yarn v1.22.17

Additional context

About this issue

  • Original URL
  • State: open
  • Created 2 years ago
  • Comments: 20 (6 by maintainers)

Most upvoted comments

@Theiaz šŸ‘ I think it should work for @stephan-roolvink as well because you were in fact encountering another issue

The issue @sevilyilmaz has is another one, and we need @xanf feedback

@stephan-roolvink @Theiaz Yes, you are probably encountering #1869 We already have a fix, we just need to merge and release it.