Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Bug: data callback on mount/shallowmount does not work for composition / class component #1879

Closed
AWoelfel opened this issue Nov 21, 2022 · 4 comments
Labels
bug Something isn't working

Comments

@AWoelfel
Copy link

Describe the bug
i use <script setup/> composite component api and want to use the data : () => Record<string, unknown> callback in mount/shallowmount

To Reproduce
following test fails if used with the component below

it('should handle setData on composition api component', async () => {
    const wrapper = mount(SimpleData)
    expect(wrapper.html()).toEqual(
      '<div>sArray:[\n  "initialA",\n  "initialB"\n  ]|s:initialC</div>'
    )

    await wrapper.setData({
      dataStringArray: ['setA', 'setB'],
      dataString: 'setC'
    })

    expect(wrapper.html()).toEqual(
      '<div>sArray:[\n  "setA",\n  "setB"\n  ]|s:setC</div>'
    )
  })

Component SimpleData.vue

<template>
  <div>sArray:{{dataStringArray}}|s:{{dataString}}</div>
</template>


<script setup lang="ts">

import {ref} from "vue";

const dataStringArray = ref<string[]>(["initialA","initialB"])
const dataString = ref<string>("initialC")

</script>

while this test (using an inline declaration will not fail)

  it('should handle setData on inline component component', async () => {
    const Component = {
      template: `<div>sArray:{{dataStringArray}}|s:{{dataString}}</div>`,
      data: () => ({
        dataStringArray: ['initialA', 'initialB'],
        dataString: 'initialC'
      })
    }
    const wrapper = mount(Component, {
      data: () => {
        return {
          dataStringArray: ['setA', 'setB'],
          dataString: 'setC'
        }
      }
    })

    expect(wrapper.html()).toEqual(
      '<div>sArray:[\n  "setA",\n  "setB"\n  ]|s:setC</div>'
    )
  })

Expected behavior
both tests should not fail

Related information:

  • @vue/test-utils version: 2.2.4
  • Vue version: 3.2.33
  • node version: 16.18.0
  • npm version: 8.19.2
@AWoelfel AWoelfel added the bug Something isn't working label Nov 21, 2022
@cexbrayat
Copy link
Member

Hi @AWoelfel

This is expected (and mentioned in the docs, see https://test-utils.vuejs.org/api/#setdata)

If you want to update the internal state of a script setup component, you can use wrapper.vm.dataString = 'hello'; await nextTick();. setData is only working for components declared with the options API

@cexbrayat cexbrayat closed this as not planned Won't fix, can't repro, duplicate, stale Nov 21, 2022
@AWoelfel
Copy link
Author

Hi @cexbrayat
Can you clearify why this is expected behaviour?

Besides my problems i found #1058 ; wrote a fix and, to this second, prepare a PR to support both setData and data : () => {} callback for composite and class components.

I do not like to use wrapper.vm.dataString = 'hello'; await nextTick(); as this triggers a lot of events/updates on my components which messes up my component states during tests.

Thanks in advance!

Alex

@cexbrayat
Copy link
Member

setData is still in VTU v2 for components written with the options API.
The class component API is no actively maintained and is not generally recommended by the Vue team: vuejs/core#4744 (comment)

Note that setData returns nextTick so this does the same as wrapper.vm.dataString = 'hello'; await nextTick(); if you do await wrapper.setData(). If you don't, you can use wrapper.vm.dataString = 'hello'.

It would look strange to me to use setData in Composition API components, as the data field no longer exists.
You can open a PR and we'll take a look, but I can't guarantee this will get merged.

@AWoelfel
Copy link
Author

AWoelfel commented Nov 21, 2022

Thx!

On my side, i primarly like to mount/shallowmount a component with a predefined state on the data properties.
This was the first thing i fixed and than found issue #1058 and though the setData and initial data setup are both usefull from my point of view.

I was not aware of the fact setData was build for the option api; thx for this info!

edit:

I am aware that the component propagates all events with await nextTick() while using setData().
I can write my tests around this fact but rather would be able to set a state for all data element with the call of mount/shallowmount. This would totally improve our test cases IMO.

Alex

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

2 participants