testing-library / vue-testing-library

🦎 Simple and complete Vue.js testing utilities that encourage good testing practices.
http://testing-library.com/vue
MIT License
1.06k stars 110 forks source link

Value emitted inside a component from an asynchronous function is undefined. #271

Closed ECJ222 closed 2 years ago

ECJ222 commented 2 years ago

When trying to listen to events emitted inside a component from an asynchronous function, for some reason the emitted() query doesn't see those kind of events, Check the example below, I also added a screenshot.

Relevant code or config (if any)

Test:

describe('Camera component', () => {
   test('take a photo', async () => {
      const { getByTestId, emitted } = render(Camera, {
         props: {
           cameraOpened: true
         }
       })

      const cameraButton = getByTestId('camera-button') as HTMLElement
      await fireEvent.click(cameraButton)

     console.log(emitted()) // <- returns an empty object

     expect(emitted()['captured-image']).toHaveProperty('length', 1) // <- this fails.
  })
})

Component:

async takePhoto (): Promise<void> {
    const capture = this.getCanvas().toDataURL('image/jpeg')

    const res = await this.convertBase64ToFile(capture)

    this.$emit('captured-image', {
      file: res,
      localUrl: capture
    })
  }

Expected:

Screen Shot 2022-06-08 at 11 27 24 AM
[Object: null prototype] {
  'captured-image': [ [ [Object] ] ],
}

Returns

Screen Shot 2022-06-08 at 11 25 59 AM
[Object: null prototype] {}
afontcu commented 2 years ago

Hi,

could you share a small reproduction repo/codesandbox or similar with a full component? This should definitely work but it is hard to tell without actually seeing the whole data flow.

btw, could you give waitFor a quick go? Something like: await waitFor(() => expect(emitted()['captured-image']).toHaveLength(1))

ECJ222 commented 2 years ago

Yes, @afontcu, that worked looks like all I needed to do was wait for the promise to be resolved before the events could be emitted.

Thank you!