6

I'm playing with mount() from vue-test-utils, have a component that imports services that should be mocked in the unit test.

I see that mount() has a mocks option, but trying to extrapolate the example given at guides, common-tips, mocking injections to the scenario of an injected service is eluding me.

mount(Component, {
  mocks: {
    ...?
  }
})

The component simply imports the service, which is plain JS

import DataService from '../services/data.service'

I can get it working using the inject-loader which is detailed here Testing With Mocks

The code that does work

const MyComponentInjector = require('!!vue-loader?inject!./MyComponent.vue')
const mockedServices = {
  '../services/data.service': {
    checkAll: () => { return Promise.resolve() }
  },
}
const MyComponentWithMocks = MyComponentInjector(mockedServices)

const wrapper = mount(MyComponentWithMocks, { store: mockStore, router })

What is the syntax for mount(MyComponent, { mocks: ... })?

Since mount() has a mocks option, should it not be possible to pass mockedServices to it in some form?

1 Answer 1

5

mocks refers to the Vue instance. You're trying to mock a file dependency, which is a different problem. As you said, one solution is inject-loader. Another is the babel-plugin-rewire.

Let me clear up what the mocks option does.

mocks adds properties to the Vue instance.

If you have an app that injects $route, you might have a component that tries to access it: this.$route.path:

...
  methods: {
    logPath() {
      console.log(this.$route.path)
    }
  } 
... 

If you try to mount this component without installing Vue router, it will throw an error. To solve this, you can use the mocks mount option to inject a mock $route object to the Vue instance:

const $route = { path: 'some/mock/value' }
mount(Component, {
  mocks: {
    $route
  }
})
Sign up to request clarification or add additional context in comments.

4 Comments

Cheers Edd, I saw from add-mocks.js that the mocks options just adds properties to the instance. Coming from Angular where injected dependencies do end up as instance properties, I was thinking the same for Vue. Purely as an experiment, I set up my service as an instance property with created () { this.dataService = DataService }. I could then mock it without the injector, but not in mount's mocks option, I had to replace it on wrapper.vm after mount. I guess from that the injector is running after add-mocks runs.
Yep, the mocks run before we create an instance
A further note, the documented way of mocking with injector doesn't quite feel right (multiple steps, injection key is a path string rather than a dependency name). Adding vue-inject to the project makes mocking services easier.
So, just to be clear: vue-test-utils does not support mock injection out of the box? It looks like only the long form works with inject loader, is that correct?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.