vuejs / test-utils

Vue Test Utils for Vue 3
https://test-utils.vuejs.org
MIT License
1.04k stars 244 forks source link

Bug: Component with Async Setup wrapped in Suspense doesn't support HTML Snapshots? #1756

Closed markabruce closed 2 years ago

markabruce commented 2 years ago

Describe the bug When a component uses async setup and it's parent component wraps it in a suspense, when running a .html snapshot test, the HMTL snapshot remains empty.

To Reproduce Here is a little noddy project I created to reproduce this issue: https://github.com/markabruce/Vue3SuspenseAsyncSetupHTMLSnapshotIssue

Steps:

  1. Create a component with an async setup and include some awaiting function call in setup
  2. Wrap child component with the async setup in a Suspense within the parent component
  3. Create a test following the vue-test-utils docs: https://test-utils.vuejs.org/guide/advanced/async-suspense.html#testing-asynchronous-setup
  4. expect(wrapper.html()).toMatchSnapshot();

Expected behavior wrapper.html() should return the HTML of the component.

Related information:

"dependencies": {
    "core-js": "^3.8.3",
    "vue": "^3.2.13"
  },
  "devDependencies": {
    "@babel/core": "^7.12.16",
    "@babel/eslint-parser": "^7.12.16",
    "@vue/cli-plugin-babel": "~5.0.0",
    "@vue/cli-plugin-eslint": "~5.0.0",
    "@vue/cli-plugin-unit-jest": "~5.0.0",
    "@vue/cli-service": "~5.0.0",
    "@vue/test-utils": "^2.0.0-0",
    "@vue/vue3-jest": "^27.0.0-alpha.1",
    "babel-jest": "^27.0.6",
    "eslint": "^7.32.0",
    "eslint-plugin-vue": "^8.0.3",
    "jest": "^27.0.5"
  },

Additional context None, thanks in advance.

freakzlike commented 2 years ago

You are using setTimeout. Are you mocking the timer? https://jestjs.io/docs/timer-mocks

markabruce commented 2 years ago

Apologies, forgot to do that in the noddy project, but have done it in my own on the beforeEach before creating the wrapper:

subscriptionTiersModuleActions.getSubscriptionTiers.mockResolvedValue(expectedSubscriptionTiers);

userSubscriptionModuleActions.getUserSubscription.mockResolvedValue(userSubscriptionTierOne);

I can update the noddy project and make sure though - will have to be after work.

markabruce commented 2 years ago

Ok, had some time, got it to run:

beforeEach(async () => {
    jest.useFakeTimers();
    const ChildAsyncSetupComponentWrappedInSuspense = defineComponent({
      components: { ChildAsyncSetupComponent },
      template: '<Suspense><ChildAsyncSetupComponent/></Suspense>'
    })

    wrapper = mount(ChildAsyncSetupComponentWrappedInSuspense);

    jest.runAllTimers();

    await flushPromises();
    await nextTick();
});

Snapshot:

    + <!-- eslint-disable max-len -->
    + <div>This is the Async Setup Component</div>
    + <!-- eslint-enable max-len -->

Closing this, there must be something I've not configured correctly with my mocks.

Thanks for the help and apologies for raising this unnecessarily!

markabruce commented 2 years ago

Just to note, it was because my project was on test utils v2.0.0-rc18 - I've upgraded it to v2.0.0