vuejs / test-utils

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

Bug: Unable to mock original mixin method in the component with Vue 3. #2455

Open gsamal opened 4 months ago

gsamal commented 4 months ago

Describe the bug

I am trying to mock the mixins used in the Vue component by passing in a fake mixin under global.mixins. But it seems to be not working on the Component while on the child component I can see the mocked method.

No difference on switching from shallowMount to mount.

To Reproduce

common-chart.vue
<template>
  <div class="fill-height">
    <widget-export-as-image @click="downloadAsImage" />
  </div>
</template>
<script>
import chartMixin from './../mixins/chart-mixin';
import WidgetExportAsImage from '../../common/widget-export-as-image/widget-export-as-image';
export default {
  components: {
    WidgetExportAsImage
  },
  mixins: [chartMixin],
  props: {
    widget: { type: Object, required: true }
  },
  data() {
    return {};
  }
};
</script>
chart-mixin.vue
<script>
export default {
  props: {
    widget: { type: Object, required: true }
  },
  created() {
    console.log('Original mixins created');
  },
  methods: {
    downloadAsImage(type) {
      console.log('Original mixins downloadAsImage');
    }
  }
};
</script>
test.spec.js
import { shallowMount } from '@vue/test-utils';
import CommonChart from './common-chart';

const mockMixin = {
  created() {
    console.log('mock mixin created');
  },
  methods: {
    downloadAsImage() {
      console.log('mock mixin downloadAsImage');
    }
  }
};

let wrapper;

describe('Common chart', () => {
  it.only('testing mixins', async () => {
    wrapper = shallowMount(CommonChart, {
      props: {},
      global: {
        plugins: [],
        mocks: {},
        mixins: [mockMixin]
      }
    });
    await wrapper.vm.$nextTick();
    let widgetExportAsImageWrapper = wrapper.findComponent('widget-export-as-image-stub');
    console.log('Rendered HTML - \n', wrapper.html());

    wrapper.vm.downloadAsImage(); // Points to the original import
    widgetExportAsImageWrapper.vm.downloadAsImage(); // Points to the mocked mixin
  });
});
Test output
mock mixin created
mock mixin created
Original mixins created
mock mixin created
Rendered HTML - 
 <div class="fill-height">
  <widget-export-as-image-stub></widget-export-as-image-stub>
</div>
Original mixins downloadAsImage
mock mixin downloadAsImage

Expected behavior

wrapper.vm.downloadAsImage() should call to the mocked mixins method when invoked.

Related information:

  System:
    OS: Linux 5.15 Ubuntu 20.04.6 LTS (Focal Fossa)
    CPU: (8) x64 Intel(R) Core(TM) i5-10210U CPU @ 1.60GHz
    Memory: 8.48 GB / 15.38 GB
    Container: Yes
    Shell: 5.0.17 - /bin/bash
  npmPackages:
    @vue/test-utils: 2.4.6 => 2.4.6 
    vitest: 1.6.0 => 1.6.0 
    vue: 3.4.13 => 3.4.13 
cexbrayat commented 2 months ago

Hi @gsamal

If you are still encountering this issue, can you provide us a small repro online using https://stackblitz.com/github/vuejs/create-vue-templates/tree/main/typescript-vitest?file=src%2Fcomponents%2F__tests__%2FHelloWorld.spec.ts ?

It only takes a few minutes, and we'll be able to take a look

gsamal commented 1 month ago

@cexbrayat here is the link to reproduce - https://stackblitz.com/edit/github-g3hyfh?file=src%2Fcomponents%2F__tests__%2FHelloWorld.spec.ts

Do note that the tests are passing but the last two consoles are not as expected. From

    wrapper.vm.downloadAsImage(); // Points to the original import - Should be pointing to the mocked mixin???
    widgetExportAsImageWrapper.vm.downloadAsImage(); // Points to the mocked mixin