Vue-test-utils: Pass mocks object to global config

Created on 3 Jan 2018  Â·  14Comments  Â·  Source: vuejs/vue-test-utils

Hi,

I have a feature request/idea.

I work in a non English speaking country, so we are using vue-i18n to create a bilingual app. It adds a global $t function. I have to do:

mocks: {
  $t: jest.fn()
}

in every test, or the test fails with $t is undefined, since almost all components have some form of text.

Should this be something handled by a test running? Not sure - if not, maybe we can have some way to set some default options for all tests, or all shallow renders or something.

feature request intend to implement

All 14 comments

We already have a global config to add stubs.

I think it would be useful for people to have a global config for mocks too. The local mounting options would overwrite the mocks set in the config if they clash.

Would you like to make a PR to implement this?

I would like to make it! Do you have a good place I can look to get started?

Sorry the slow reply.

Edit: got something working using a similar way to config stubs. But it would be nice to have a config file (.js) we could load options from?

Do you want to make a PR with the original way, using the config object.

We should start another discussion about whether to support a config file or not.

It seems like you can do the same thing at stubs in the current master, simply mocks['myMock'] = jest.fn() for example.

Maybe we should discuss a config file first before going any further.

Exact same issue as @lmiller1990. Also things like ElementUI's $alert,$confirm or own global helpers we have can be easily mocked everywhere :)

Yes please - big problem :(

A simple work around you can use in the meantime, before we solve the global config problem, is to make a helper with all your commonly used mocks, for example:

// Let's call it mocks.js
import { shallow } from '@vue/test-utils'

const mocks = {
  $t: () => {} // I always mock vuei18n
}

const shallowWithMocks = (component, otherData, otherMocks) => shallow(component, { 
  mocks: {
    ..mocks, ...otherMocks
  },
  ...otherData 
})

export shallowWithMocks
import { shallowWithMocks } from './mocks.js'

const wrapper = shallowWithMocks(component, { 
  propsData: { /* */ }
})

Note: I didn't test this, but I have something similar in a project somewhere. It probably has some typos.


I still think a config file would be good. I'd like to work on it, but not sure where to start. Maybe we can start by fleshing out an API? I'm thinking something along the lines of a test-utils.config.js that could be something like this:

export default {
  mocks: {
    // mocks to use in all tests
    // they should be merged with any mocks passed in `shallow` or `mount`
    // the ones from `shallow`, `mount` should take priority and override the ones in this config file
  },
  stubs: {
    /* I often find myself wanting to stub certain components a lot as well */
  }
}

You should be able to provide defaults for anything you can pass in the options object to shallow and mount.

vue-test-utils shouls look for a default config file in the root directory (for example test-utils.config.js.

I'd like to hear thoughts of everyone else too before starting hacking.

I believe there are two issues here:

  1. Ability to add mocks to global mocks object (like VueTestUtils.config.stubs
  2. Support a config file

I think we can go ahead and add mocks to the existing config object. We can create a separate issue for adding a config file.

@lmiller1990 would you like to create a PR that adds the ability to pass mocks to the config object?

@eddyerburgh Sure. I'll look at the existing way we do it with stubs and mimic that.

Good idea, we should make another issue for config. I can do that this evening, and add a summary of the discussion in here.

âž• for separated js config file

Here is issue for discussion around a separate config file: https://github.com/vuejs/vue-test-utils/issues/523

@eddyerburgh I had a go at implementing this just now. I hadn't used the config object before. I did the following. The reproduction repo link is here:

  • new project with vue-cli v3, using jest
  • Create a TestStub.vue, containing <template><div>TestStub</div></template>
  • In, HelloWorld.vue, import TestStub.vue and add it to the <template> markup
  • In HelloWorld.spec.js, stub TestStub.vue with by doing
const wrapper = shallow(HelloWorld, {
  stubs: {
    'TestStub': '<div>T</div>'
  }
})

console.log(wrapper.html()) yields:

<div class="hello"><div>T</div></div>

So far so good. Next, I decided to try using the config object. In HelloWorld.spec.js, this works:

import { shallow } from '@vue/test-utils'
import HelloWorld from '@/components/HelloWorld.vue'
const VueTestUtils = require('@vue/test-utils')

VueTestUtils.config.stubs['TestStub'] = '<div>T</div>'

describe('HelloWorld.vue', () => {
  it('renders props.msg when passed', () => {
    const wrapper = shallow(HelloWorld)

    console.log(wrapper.html())
  })
})

Now my question: where should I be able to define VueTestUtils.config to make it applicable in every unit test? I tried this in jest.config.js:

require('jsdom-global')()

const VueTestUtils = require('@vue/test-utils')

VueTestUtils.config.stubs['TestStub'] = '<div>A</div>'

But doing so had no impact in my tests - all components became <!----> instead of inheriting the config as expected. I added require('jsdom-global')() since otherwise VueTestUtils throws errors.

After I understand where I should be able to do global mocks, I will be able to add mocks to the config, then start on #523 . Repo is here

Thanks for this great lib!

You can use the Jest setupFiles option to run a file before the tests.

This has been added and will be released in beta.15

Was this page helpful?
0 / 5 - 0 ratings