0

I have a vue2 project that uses ClassComponents and Chart.js (via vue-chart-3). I now have a simple component that wraps a DoughnutChart to manage data and stuff.

DBOverviewDoughnut.vue

<template>
  <div>
    <p>test</p>
    <DoughnutChart ref="doughnutRef" :chartData="sharesData"></DoughnutChart>
  </div>
</template>

<script lang="ts">
import Component from 'vue-class-component';
import Vue from 'vue';
import { DoughnutChart, ExtractComponentData } from 'vue-chart-3';
import { Prop, Ref } from 'vue-property-decorator';
import { ChartData } from 'chart.js';

@Component({ components: { DoughnutChart } })
export default class DBOverviewDoughnut extends Vue {
  @Prop()
  private sharesData!: ChartData<'doughnut'>;

  @Ref()
  private readonly doughnutRef!: ExtractComponentData<typeof DoughnutChart>;

  created(): void {
    this.assignColors();
  }

  mounted(): void {
    if (this.doughnutRef.chartInstance) {
      console.log(this.doughnutRef.chartInstance.data);
    }
  }

  assignColors(): void {
    this.sharesData.datasets[0].backgroundColor = [
      '#77CEFF',
      '#0079AF',
      '#123E6B',
      '#97B0C4',
      '#A5C8ED',
    ];
  }
}
</script>

Starting the program it will work fine and I can access the chartInstance inside the mounted hook.

But now I want to unit test my component. I thought on setting the propsData which will be the input data for the chart.

DBOverviewDoughnut.spec.ts

import DBOverviewDoughnut from '@/components/dashboard/DBOverviewDoughnut.vue';
import { mount, Wrapper } from '@vue/test-utils';
import { Share } from '@/Share';

describe('DBOverviewDoughnut', () => {
  let cut: Wrapper<DBOverviewDoughnut>;

  it('should render the correct amount of sections', () => {
    cut = mount(DBOverviewDoughnut, {
      propsData: {
        sharesData: {
          labels: ['TestShare1', 'TestShare2', 'TestShare3'],
          datasets: [{ data: [11, 22, 33] }]
        }
      }
    });
    const chart = cut.findComponent({ ref: 'doughnutRef' });
    console.log(chart);
  });
});

Using shallowMount() doesn't seem to work, because I only get this from logging (no chartInstance and its properties as in the production code):

VueWrapper {
      isFunctionalComponent: undefined,
      _emitted: [Object: null prototype] {},
      _emittedByOrder: [],
      selector: { ref: 'doughnutRef' }
    }

So I thought maybe I have to mount the component because the DoughnutChart is also a wrapper around the Chart.js charts. But when using mount() I get the following error:

console.error node_modules/vue/dist/vue.runtime.common.dev.js:621
    [Vue warn]: `createElement()` has been called outside of render function.

  console.error node_modules/vue/dist/vue.runtime.common.dev.js:621
    [Vue warn]: Error in render: "Error: [vue-composition-api] must call Vue.use(VueCompositionAPI) before using any function."
    
    found in
    
    ---> <DoughnutChart>
           <DBOverviewDoughnut>
             <Root>

I don't really know what I'm doing wrong. I registered the VueCompostionAPI in my main.ts:

import Vue from 'vue';
import { Chart, registerables } from 'chart.js';
import App from './App.vue';
import router from './router';
import store from './store';
import VueCompositionAPI from '@vue/composition-api';

Chart.register(...registerables);
Vue.use(VueCompositionAPI);

new Vue({
  router,
  store,
  render: (h) => h(App),
}).$mount('#app');

Following this post doesn't solve the problem either.

Anyone got an idea what's going wrong? I'm a bit confused if the error has to do with my test setup or with the installation of chart.js or compositionApi.

1
  • what is the test you want to do ? Commented Jan 1, 2022 at 17:50

2 Answers 2

1

You need to use VueCompositionAPI inside your spec as well when you mount the component. You can do this by creating a local Vue instance inside your spec, adding VueCompositionAPI as a plugin to the instance and using the instance when you mount the component. https://vue-test-utils.vuejs.org/api/options.html#localvue

Sign up to request clarification or add additional context in comments.

1 Comment

As it’s currently written, your answer is unclear. Please edit to add additional details that will help others understand how this addresses the question asked. You can find more information on how to write good answers in the help center.
0

Using localVue is really what I should have thought about. This and installing the canvas-package works, that I get additional information about my Ref-Element. However I still have to figure out what to do with it.

@AdriHM I want to test if the rendered chat gets the correct data I guess. Or if it displays it correctly (e.g. display the correct amount of sections) But the longer I think about it the less I'm sure it's the right thing to test. I don't want to test the Chart.js API though.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.