'How can i create fake functions to test the components?

I have to test my component, but that component have a function for that it can work. This function need a key environment.

My component has a onMounted function

 onMounted(async () => {

    const available = await getAvailableBills()
 }

and the implementation is:

export const getAvailableBills = async () => {
  try {
    const bill = `${process.env.VAR_ENV}`

I am getting this error:

Error: Provided address {VAR_ENV} is invalid

But I Think I don't need to execute the real functions. I would like to create fake functions in my test

import { shallowMount } from '@vue/test-utils'
import { createApp } from 'vue'
import { createStore } from 'vuex'
import App from '@/components/tables'

const store = createStore({
  state() {
    return {
      user: {},
    }
  },
  mutations: {},
})

let wrapper
const app = createApp(App)
app.use(store)
beforeEach(() => {
  wrapper = shallowMount(App, {
    propsData: {
      whitelist: [1,2,3],
    },
    global: {
      plugins: [store],
    },
  })
})

describe('Tables', () => {
  it('test 1', () => {
    expect(wrapper.props().list).toEqual([1,2,3])
  })
})


Solution 1:[1]

You have to mock it. It seems like you're using jest. You can use jest.spyOn method to mock a particular object, or mock the whole file using jest.mock.

For example, if you have

src /
- app.js
- app.spec.js
- services /
--- bills.js

In your src/app.spec.js, if you're exported function getAvailableBills is in src/services/bills.js, just do this :

import { shallowMount } from '@vue/test-utils'
import { createApp } from 'vue'
import { createStore } from 'vuex'
import App from '@/components/tables'

import { getAvailableBills } from './services/bills'
jest.mock('./services/bills', {
  getAvailableBills: jest.fn().mockResolvedValue({ bills: ['...'] }) // you can mock the response directly here for the whole file
})

getAvailableBills.mockResolvedValue({ bills: ['...'] }) // or you can mock the response when you need to mock it

const store = createStore({
  state() {
    return {
      user: {},
    }
  },
  mutations: {},
})

let wrapper
const app = createApp(App)
app.use(store)
beforeEach(() => {
  wrapper = shallowMount(App, {
    propsData: {
      whitelist: [1,2,3],
    },
    global: {
      plugins: [store],
    },
  })
})

describe('Tables', () => {
  it('test 1', () => {
    expect(wrapper.props().list).toEqual([1,2,3])
  })
})

Notice that I used mockResolvedValue because it's returning a Promise (async method), but if it returns a direct value and not a promise, use mockReturnValue. You can also mock only once when needed with mockResolvedValueOnce and mockReturnValueOnce, or mock a rejected promise with mockRejectedValue.

Btw, you better encapsulate the tests inside describe, it avoids some errors, and it makes more readable & writable tests. You should also mock inside beforeAll / beforeEach methods to mock once for multiple tests when needed.

If needed, you can also add a setup files where you instantiate fake env values inside jest.config. That's not the point but it may help you one day.

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