Skip to content

setData does not force a re-render of the component when using v-model, data(), and a computed property #514

@s-robertson

Description

@s-robertson

Version

1.0.0-beta.13

Reproduction link

https://github.com/s-robertson/vtu-setdata

Steps to reproduce

Create a new Vue component with the following criteria:

  1. Have data() return an object containing an empty string, e.g. msg
  2. Have a computed property that returns a boolean depending on if msg is empty or not. E.g. hasMsg
  3. Have an <input> in the component template that uses v-model, bound to msg
  4. Have an element, such as an <h1> in the component template that uses v-if, bound to hasMsg. This element must come AFTER the <input> in the template

Now write a unit test that:

  1. Mounts the component via shallow()
  2. Calls setData and sets msg to a non-empty string
  3. Checks to see if the template contains the <h1>

Finally, run the unit test.

What is expected?

Calling setData will cause the component to re-render, making hasMsg be true and the test will pass.

What is actually happening?

Calling setData does not cause the component to re-render. The unit test cannot find the <h1> element and fails:

 FAIL  tests/unit/HelloWorld.spec.js
  HelloWorld.vue
    ✕ renders props.msg when passed (36ms)

  ● HelloWorld.vue › renders props.msg when passed

    expect(received).toBe(expected) // Object.is equality
    
    Expected value to be:
      true
    Received:
      false

       9 |     wrapper.setData({ msg });
      10 | 
    > 11 |     expect(wrapper.contains('h1')).toBe(true);
      12 |   })
      13 | });
      14 | 
      
      at Object.<anonymous> (tests/unit/HelloWorld.spec.js:11:36)

Test Suites: 1 failed, 1 total
Tests:       1 failed, 1 total
Snapshots:   0 total
Time:        1.062s
Ran all test suites.
 ERROR  jest exited with code 1.
error Command failed with exit code 1.

What's interesting is that the order of the <input> and <h1> in the template matters. If the <h1> comes before the <input> the test will also pass.

You can also get the test to pass by forcefully updating the component via wrapper.vm.$forceUpdate(); after you've called setData.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions