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

Stubs rendering default props #945

Open
robokozo opened this issue Sep 14, 2021 · 8 comments
Open

Stubs rendering default props #945

robokozo opened this issue Sep 14, 2021 · 8 comments
Labels
discussion enhancement New feature or request

Comments

@robokozo
Copy link

When rendering snapshots, stubbed components are actually being evaluated in order to apply the default props to the element.

For example if my component imports and contains the following code:

<Button
      ref="cancel-button"
      label="Cancel"
      :disabled="isLoading"
      icon="pi pi-times"
      @click="cancelClickHandler"
      class="p-button-text"
    />

And I stub out the Button component in my test

mountOptions = {
      global: {
        stubs: ["Button"]
      }
    }

My snapshot will render with
<button-stub label="Cancel" icon="pi pi-times" iconpos="left" loading="false" loadingicon="pi pi-spinner pi-spin" disabled="false" class="p-button-text"></button-stub>

iconpos="left" and loadingicon="pi pi-spinner pi-spin" should not be rendered.

This is annoying for me because whenever I update my Button component my snapshots for anything using the Button component need to be updated. I already have my Button component covered with its own tests so this is unnecessary.

@lmiller1990
Copy link
Member

lmiller1990 commented Sep 20, 2021

Hey John. Where are loadingicon and iconpos coming from? I don't see them anywhere in the example.

Snapshots + stubs are difficult to handle - seems like there are varying opinions on what should and should not be rendered. I wonder if we can provide a few different snapshot serializers, so people can choose the snapshot behavior they'd like. 🤔

@lmiller1990 lmiller1990 added discussion enhancement New feature or request labels Sep 20, 2021
@robokozo
Copy link
Author

They are defined on the actual "Button" component that I'm stubbing out. These specific props are defined with default values that are being rendered by the snapshot. (In this particular case they are defined in the PrimeVue component library I'm using)

I'm assuming that the actual Button component is being evaluated before the stubbing process takes place.

@robokozo
Copy link
Author

I'm assuming that the actual Button component is being evaluated before the stubbing process takes place.

I ran into another issue which leads me to believe this is the case and the stubbing process should be examined. In this new situation, one of my stubbed components has dependencies which are not accounted for in the context of the test. The test crashes... but it shouldn't matter because the component should be stubbed out.

@lmiller1990
Copy link
Member

What do you mean by "has dependencies"? As in it imports other modules? The stubbing VTU offers is just before the component is rendered; it will still get imported (as well as all its dependencies).

Assuming my understanding of your question is correct, if you want to completely and totally stub out a component (and the modules it imports) you could use jest.mock potentially.

@robokozo
Copy link
Author

Yeah I think you understood correctly. Your idea to use jest.mock sounds really interesting! I'll give it a go!

@lmiller1990
Copy link
Member

Cool, here is a basic example: https://lmiller1990.github.io/vue-testing-handbook/vue-router.html#workaround-for-large-render-trees-using-mount

We should still fix the stubbing bug for <script setup>.

@posva
Copy link
Member

posva commented Oct 18, 2021

I'm also experiencing this in https://github.com/posva/vue-router-mock/ where the existing test fails:

    const wrapper = mount(
      {
        template: `<router-link to="/">Hello</router-link>`,
      },
      { global: { stubs: { RouterLink: true } } }
    )

    expect(wrapper.html()).toMatchInlineSnapshot(
      `"<router-link-stub to=\\"/\\"></router-link-stub>"`
    )
    Snapshot name: `components stubs router link 1`

    Snapshot: "<router-link-stub to=\"/\"></router-link-stub>"
    Received: "<router-link-stub to=\"/\" replace=\"false\" custom=\"false\" ariacurrentvalue=\"page\"></router-link-stub>"

Here is a boiled down repro @lmiller1990:

  it('fails', () => {
    const wrapper = mount(
      {
        template: `<Thing />`,
        components: {
          Thing: {
            props: {
              one: {
                type: String,
                default: 'not-rendered',
              },
            },
          },
        },
      },
      {
        global: {
          stubs: {
            Thing: true,
          },
        },
      }
    )

    expect(wrapper.html()).toMatchInlineSnapshot(
      `"<thing-stub></thing-stub>"`
    )
  })

This test currently fails at the snapshot because it renders the one attribute with the value not-rendered

@freakzlike
Copy link
Collaborator

You can define your own way how stubs are created by a plugin (plugins.createStubs). https://test-utils.vuejs.org/guide/extending-vtu/plugins.html#stubs-plugin

sadafrangian3 pushed a commit to sadafrangian3/router-mock-repository-vue that referenced this issue Sep 21, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
discussion enhancement New feature or request
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants