lukaszkups
lukaszkups

Reputation: 5980

How to mock global Vue.js variable in JEST test

I have a global property/variable with my app urls:

Vue.prototype.$apiUrls = {
  root: 'http://localhost:8080/',
  api: 'api/v1/'
  // etc.  
}

I use it inside my components as axios request:

axios.get(`${this.$apiUrls.root}${this.$apiUrls.api}/users/`)

Now I want to test my component's code, I've mocked axios already, but still I receive an error:

TypeError: Cannot read property '$apiUrls' of undefined

I've tried to define/mock this property inside each test and/or in JEST's setup file, like e.g.

global.$apiUrls = {...}
// or
Vue.prototype.$apiUrls = {...}
// or
Object.defineProperties(Vue.prototype, {$apiUrls: {...}})

I've also tried mocking it to window or this (yeah, thats silly), but with no success - I still receive that error - please help.

Upvotes: 15

Views: 17620

Answers (3)

user10706046
user10706046

Reputation:

I don't think the answers above work anymore (in 2020).

Here's what worked for me:

For vue-test-utils 1.x.x (Vue 2)

  1. Create a new file, name it eg. jest.init.js
  2. Give it the following content:
import { config } from "@vue/test-utils";
config.mocks["yourGlobalProperty"] = label => label; //you can replace it with your own mock
  1. Add this to your jest.config.js (actually write "rootDir", don't replace anything with a real path)
module.exports = {
  setupFiles: ["<rootDir>/jest.init.js"]
}

These files will be only ran before jest runs unit tests.

Note that I'm importing {config}, not the default export. I don't know why the default didn't work for me. Even the documentation for vue test utils doesn't import the default export anymore

Also make sure you're not trying to import from the old vue-test-utils package. (The new one is @vue/test-utils)

For @vue/test-utils 2.x.x (vue-test-utils-next) (Vue 3)

Follow steps like for 1.x.x above, but in step two, do this instead:

import { config } from "@vue/test-utils"; //2.0.0-beta.5
config.global.mocks = {
  yourGlobalProperty: label => label
};

Upvotes: 5

lmiller1990
lmiller1990

Reputation: 945

There is two ways to achieve this. One is using the Config option, as mentioned by @Aldarund. You can read about it here.

If you are using Jest, I recommend doing this in the jest.init.js file:

import { config } from '@vue/test-utils'

config.mocks['$apiUrls'] = {
  'some/endpoint'
}

Then add this to the jest section of your package.json:

"setupFiles": [
  "<rootDir>/jest.init.js"
]

Now it is globally mocked. If you want to do this on a per test basis, you can use the mocks mounting option:

const wrapper = shallowMount(Foo, {
  mocks: {
    $apiUrls: 'some/endpoint'
  }
})

Hopefully this helps!

If you are interested I am compiling a collection of simple guides on how to test Vue components here. It's under development, but feel free to ask make an issue if you need help with other related things to testing Vue components.

Upvotes: 15

Aldarund
Aldarund

Reputation: 17621

You can do it with vue-test-utils beta 15 and later.

Here docs

And some example would be:

import VueTestUtils from '@vue/test-utils'

VueTestUtils.config.mocks['$apiUrls'] = {
  ...
}

Upvotes: 2

Related Questions