'Injecting data into a vue3 vitest

I've written a test for vue3 for one of my components:

import { describe} from 'vitest';
import { shallowMount } from '@vue/test-utils';
import ProgressBar from '@/components/ProgressBar.vue';

const messages = {
  "en-US" : {
    strings: {
      a: "A",
      b: "B",
      c: "C"
    }
  },
  "fr-CA": {
    strings: {
      a: "AA",
      b: "BB",
      c: "CC"
    }
  }
};

const locale = "en-US";

try {
  describe("ProgressBar.vue", () => {

    function stepClick() {
      console.log("step click");
    }
    
    const stepData = {
      steps: [
        { index: 1, completed: false, clickActive: false },
        { index: 2, completed: false, clickActive: false },
        { index: 3, completed: false, clickActive: false }
      ],
      currentIndex: 1
    };

    const component = shallowMount(ProgressBar, {
      props: {
        stepDataSource: "stepData",
        onClick: stepClick,
        locPage: "strings",
        locKeys:['a', 'b', 'c' ]
      },
      provide: {
        stepData() {  return stepData }
      },
      mocks: {
        '$t': (key) => { 
          const params = key.split('.');
          return messages[locale][params[0]][params[1]];
        }
      }
    });
  });
} catch (e) {
  console.log(e);
}

The component injects the specified data in properties:

stepDataSource: "stepData"

It is loaded by a method in the component:

async getStepData() {
  console.log('getStepData');
  const stepData = inject(this.stepDataSource) as StepData;
  this.data.stepData = stepData;
  const instance = getCurrentInstance();
  instance?.proxy?.$forceUpdate();
},

Which works in normal running but it doesn't seem to get passed by the test. AFAIK, my mock of locale is working.

So what am I doing wrong to inject the step data for the test? I understand that I don't actually have any tests yet, but I need to get it to mount first.



Solution 1:[1]

This is a working test. It mocks $t successfully. I gave up trying to write them in typescript, this is a javascript file in the src/tests folder. If you need additional info about how to setup the rest of the project, go ahead and ask here.

import { describe, test, it, expect } from 'vitest';
import { ref } from 'vue';
import ProgressBar from '@/components/ProgressBar.vue';
import { mount } from "@vue/test-utils";

describe("ProgressBar.vue", () => {

  const messages = {
    "en-US" : {
      strings: {
        a: "A",
        b: "B",
        c: "C"
      }
    },
    "fr-CA": {
      strings: {
        a: "AA",
        b: "BB",
        c: "CC"
      }
    }
  };
  
  const locale = "en-US";
  const clickedItems = {1: false, 2: false, 3: false};

  function stepClick(index) {
    console.log("index:" + index);

    clickedItems[index] = true;
  }
  
  const stepData = ref({
    steps: [
      { index: 1, completed: true, clickActive: true },
      { index: 2, completed: false, clickActive: true },
      { index: 3, completed: false, clickActive: false }
    ],
    currentIndex: 2
  });

  test ("Arrange ProgressBar", async () => {

    const component = mount(ProgressBar, {
      props: {
        stepData: stepData,
        onClick: stepClick,
        locPage: "strings",
        locKeys:['a', 'b', 'c']
      },
      global: {
        mocks: {
          $t: (msg) => {
            const params = msg.split('.');
            return messages[locale][params[0]][params[1]];
          }
        }
      }
    });

    let multipleActive = false;
    const progItems = component.findAll('.prog-item');
    let selectedIndex = -1;
    
    progItems.forEach((item, index) => {
      if (item.element.className.indexOf("current") > -1) {
        if (selectedIndex < 0) {
          selectedIndex =  index + 1; //indexes are 1 based for this control
        } else {
          multipleActive = true;
        }
      }
      item.find("span.prog-item-outer").trigger('click');
    });
    
    expect(!multipleActive, "Only one Progbar item is selected").toBeTruthy();
    expect(selectedIndex === 2, "Correct Progbar Item selected,").toBeTruthy();
    
    expect(clickedItems[1] && !clickedItems[2] && !clickedItems[3], "Correct progBar indexes are return and correct items are click-active").toBeTruthy();

  });

});

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 GeeWhizBang