Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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.

like image 244
lukaszkups Avatar asked Jul 06 '18 16:07

lukaszkups


People also ask

What is createLocalVue?

createLocalVue returns a Vue class for you to add components, mixins and install plugins without polluting the global Vue class. The errorHandler option can be used to handle uncaught errors during component render function and watchers.

How do I add Jest to Vue project?

Installation with Vue CLI (recommended) If you are using the Vue CLI to build your project, you can use the plugin cli-plugin-unit-jest to run Jest tests. The plugin pulls all required dependencies (including jest), creates a jest.

How do you mock a function?

There are two ways to mock functions: Either by creating a mock function to use in test code, or writing a manual mock to override a module dependency.


2 Answers

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.

like image 162
lmiller1990 Avatar answered Oct 16 '22 17:10

lmiller1990


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
};
like image 32
walnut_salami Avatar answered Oct 16 '22 17:10

walnut_salami