Home > Mobile >  Vue Testing Library won't rerender DOM when state changes
Vue Testing Library won't rerender DOM when state changes

Time:11-19

I have a component with a strait forward Edit button. The Edit button calls a method that sets isEditing to true.

There are a few input elements with v-if="isEditing", so I'm testing that those input elements are visible after the Edit button is clicked.

When my test runs fireEvent.click(screen.getByRole('link', {name: 'Edit'})), it is updating isEditing to true (based on my console.log messages before/after the .click event), but it doesn't seem to re-render the components within the test (based on the DOM rendered in my terminal after getByRole fails).

It works as expected in the browser, but doesn't seem to update the DOM for the spec. I'm using Vue2, Vue Testing Library, and Jest.

Implementation:

<template>
  <a @click.prevent="startEdit" v-if="!isEditing">Edit</a>
  <input :v-if="isEditing" />
</template>
...
methods: {
  startEdit: () => {
    this.isEditing = true
  }
}

Spec:

describe('FormComponent', () => {
  beforeEach(() => {
    render(FormComponent)
  })

  it('displays input tags' () => {
    fireEvent.click(screen.getByRole('link', {name: 'Edit'}))
    expect(screen.getByRole('input')).toBeInTheDocument()
  })

})

CodePudding user response:

It doesn't work because you wrote :v-if when it should be v-if. I guess this was simply a typo since you did it correctly the first time (v-if="!isEditing")

CodePudding user response:

The problem is your expect is running before the DOM has had a chance to update. From the testing library documentation:

Because Vue applies DOM updates asynchronously during re-renders, the fireEvent tools are re-exported as async functions. To ensure that the DOM is properly updated in response to an event in a test, it's recommended to always await fireEvent.

You should update your test to await the fireEvent promise like so:

it('displays input tags' async () => {
    await fireEvent.click(screen.getByRole('link', {name: 'Edit'}))
    expect(screen.getByRole('input')).toBeInTheDocument()
})

You also have a typo in your second v-if as Nicole pointed out in her answer.

  • Related