toHaveBeenCalled() assertion doesn't work in vue3 app

51 views Asked by At

I try to write test for my Vue 3 app and I try to test my component. In this post I will use my simple component to show my case. So I have my simple component with button and when the button is clicked my method "testFun" should be called. Inside this method I have a console.log and I can see this console.log is displayed in consol after run my test but when I want to use assertion :

"expect(testCall).toHaveBeenCalled();"

then i have this error:


    expect(jest.fn()).toHaveBeenCalled()

    Expected number of calls: >= 1
    Received number of calls:    0

      15 |     wrapper.find("button").trigger("click");
      16 |
    > 17 |     expect(testCall).toHaveBeenCalled();
         |                      ^
      18 |   });
      19 | });

I tried to use also

toHaveBeenCalledWith()

toBeCalled()

Below I will paste my component, spec file and set up.

COPOMENT:

<template>
  <button data-test="data-test" @click="testFun">TEST</button>
</template>

<script setup lang="ts">

const testFun = () => {
  console.log("TESTTEST");
};
</script>

SPEC FILE:

import HelloWorld from "./HelloWorld.vue"; 
import { mount } from "@vue/test-utils";

describe("HelloWorld", () => {
  it("renders properly", () => {
    const wrapper = mount(HelloWorld);
    const testCall = jest.spyOn(wrapper.vm, "testFun");

    wrapper.find("button").trigger("click");

    expect(testCall).toHaveBeenCalled();
  });
});

JEST CONFIG:

module.exports = {
    testEnvironment: "jsdom",
    transform: {
        '^.+\\.ts$': 'babel-jest',
        '^.+\\.js$': 'babel-jest',
        '^.+\\.vue$': '@vue/vue3-jest',
    },
    testRegex: "(/__tests__/.*|(\\.|/)(test|spec))\\.(js|ts)$",
    moduleFileExtensions: ['js', 'json', 'vue', 'ts'],
    moduleNameMapper: {
        "^@/(.*)$": "<rootDir>/src/$1",
    },
    coveragePathIgnorePatterns: ["/node_modules/", "/tests/"],
    coverageReporters: ["text", "json-summary"],
    setupFiles: ['<rootDir>/jest-setup.ts'], 
    testEnvironmentOptions: {
        customExportConditions: ["node"],
    },
}

JEST SETUP

import { config } from "@vue/test-utils"; import { createTestingPinia } from "@pinia/testing"; import ElementPlus from "element-plus";

config.global = {
  ...config.global,
  plugins: [createTestingPinia({ stubActions: false }), ElementPlus],
};

if (!window.global.activeFeatureTogglz) {
  window.global.activeFeatureTogglz = [];
}

WEBPACK CONFIG

const { ElementPlusResolver } = require('unplugin-vue-components/resolvers');

module.exports = {
  // ... other configurations
  module: {
    rules: [
      {
        test: /\.vue$/,
        loader: 'vue-loader',
      },
      // ... other rules for JS, CSS, etc.
    ],
  },
  plugins: [
    AutoImport({
      resolvers: [ElementPlusResolver()],
    }),
    Components({
      resolvers: [ElementPlusResolver()],
    }),
  ],
};

TS CONFIG

{
  "compilerOptions": {
    "target": "esnext",
    "module": "esnext",
    "strict": true,
    "jsx": "preserve",
    "importHelpers": true,
    "moduleResolution": "node",
    "skipLibCheck": true,
    "esModuleInterop": true,
    "allowSyntheticDefaultImports": true,
    "forceConsistentCasingInFileNames": true,
    "useDefineForClassFields": true,
    "sourceMap": true,
    "baseUrl": ".",
    "types": [
      "webpack-env",
      "jest",
      "element-plus/global"
    ],
    "paths": {
      "@/*": [
        "src/*"
      ]
    },
    "lib": [
      "esnext",
      "dom",
      "dom.iterable",
      "scripthost"
    ]
  },
  "include": [
    "src/**/*.ts",
    "src/**/*.tsx",
    "src/**/*.vue",
    "tests/**/*.ts",
    "tests/**/*.tsx"
  ],
  "exclude": [
    "node_modules"
  ]
}

PACKAGE JSON

{
  "name": "frontend",
  "version": "0.1.0",
  "private": true,
  "scripts": {
    "serve": "vue-cli-service serve",
    "build": "vue-cli-service build",
    "test": "jest",
    "lint": "vue-cli-service lint"
  },
  "dependencies": {
    "@element-plus/icons-vue": "^2.3.1",
    "axios": "^1.5.0",
    "element-plus": "^2.5.1",
    "pinia": "^2.1.7",
    "vue": "^3.2.13",
    "vue-router": "^4.2.4"
  },
  "devDependencies": {
    "@babel/preset-env": "^7.23.8",
    "@babel/preset-typescript": "^7.23.3",
    "@pinia/testing": "^0.1.3",
    "@types/jest": "^27.0.1",
    "@typescript-eslint/eslint-plugin": "^5.4.0",
    "@typescript-eslint/parser": "^5.4.0",
    "@vue/cli-plugin-eslint": "~5.0.0",
    "@vue/cli-plugin-typescript": "~5.0.0",
    "@vue/cli-plugin-unit-jest": "~5.0.0",
    "@vue/cli-service": "~5.0.0",
    "@vue/eslint-config-typescript": "^9.1.0",
    "@vue/test-utils": "^2.4.3",
    "@vue/vue3-jest": "^29.2.6",
    "babel-jest": "^29.7.0",
    "eslint": "^7.32.0",
    "eslint-plugin-vue": "^8.0.3",
    "flush-promises": "^1.0.2",
    "jest": "^29.7.0",
    "jest-environment-jsdom": "^29.7.0",
    "sass": "^1.69.7",
    "sass-loader": "^13.3.3",
    "ts-jest": "^27.0.4",
    "typescript": "^5.3.3"
  },
  "eslintConfig": {
    "root": true,
    "env": {
      "node": true
    },
    "extends": [
      "plugin:vue/vue3-essential",
      "eslint:recommended",
      "@vue/typescript/recommended"
    ],
    "parserOptions": {
      "ecmaVersion": 2020
    },
    "rules": {},
    "overrides": [
      {
        "files": [
          "**/__tests__/*.{j,t}s?(x)",
          "**/tests/unit/**/*.spec.{j,t}s?(x)"
        ],
        "env": {
          "jest": true
        }
      }
    ]
  },
  "browserslist": [
    "> 1%",
    "last 2 versions",
    "not dead",
    "not ie 11"
  ]
}

I tried also jest.fc(() => {}) But i had same results
I just want to see if my method was called WITH assertion, I also can change the HTML results, but want to understand my mistake.

0

There are 0 answers