Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Pass mocks object to global config #325

Closed
lmiller1990 opened this issue Jan 3, 2018 · 14 comments
Closed

Pass mocks object to global config #325

lmiller1990 opened this issue Jan 3, 2018 · 14 comments

Comments

@lmiller1990
Copy link
Member

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.

@eddyerburgh
Copy link
Member

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?

@lmiller1990
Copy link
Member Author

lmiller1990 commented Jan 5, 2018

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?

@eddyerburgh
Copy link
Member

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.

@lmiller1990
Copy link
Member Author

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.

@dobromir-hristov
Copy link
Contributor

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

@abhipanda
Copy link

Yes please - big problem :(

@lmiller1990
Copy link
Member Author

lmiller1990 commented Apr 10, 2018

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.

@eddyerburgh
Copy link
Member

eddyerburgh commented Apr 10, 2018

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?

@lmiller1990 lmiller1990 changed the title Global config object Pass mocks object to global config Apr 10, 2018
@lmiller1990
Copy link
Member Author

@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.

@iztsv
Copy link
Contributor

iztsv commented Apr 10, 2018

➕ for separated js config file

@lmiller1990
Copy link
Member Author

Here is issue for discussion around a separate config file: #523

@lmiller1990
Copy link
Member Author

lmiller1990 commented Apr 14, 2018

@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!

@eddyerburgh
Copy link
Member

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

@eddyerburgh
Copy link
Member

eddyerburgh commented Apr 20, 2018

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

5 participants