[Vuejs]-Mounting a vue instance with avoriaz, but cannot sinon spy on imported function

0👍

Problem

You need to stub the api dependency, which is a dependency of the file. This can’t be done through the vue instance, since api is not a part of the vue component.

You need to stub the file dependency.

Solution

One method to do this is to use inject-loader.

Steps

Install inject-loader

npm install --save-dev inject-loader

At the top of your file, import UploadForm with inject-loader and vue-loader:

import UploadFormFactory from '!!vue-loader?inject!@/components/UploadForm';

This is a factory function that returns UploadForm with dependencies stubbed.

Now, in your test you need to call UploadFormFactory with the dependency you want stubbed:

const api = {
  uploadFile: sinon.spy()
};

const UploadForm = UploadFormFactory({
  '@/lib/api': api
})

So your test file will look like:

import { mount } from 'avoriaz';
import { expect } from 'chai';
import sinon from 'sinon';
import UploadFormFactory from '!!vue-loader?inject!@/components/UploadForm';

describe('upload', () => {
  it('passes form data to api.uploadFile', () => {
    const api = {
      uploadFile: sinon.spy()
    };

    const UploadForm = UploadFormFactory({
      '@/lib/api': api
    })
    const testFormData = { test: 'test' };
    const api = {
      uploadFile: sinon.spy()
    };
    const wrapper = mount(UploadForm);
    wrapper.vm.upload(testFormData);
    expect(api.uploadFile.called).to.equal(true);
  });
});

More info

I’ve written a tutorial with more detail here – https://www.coding123.org/stub-dependencies-vue-unit-tests/

0👍

I think Edd’s answer is the most encompassing for most scenarios, so I’m marking his as the accepted answer. However, the workaround I came up with was to make the api library a global service (Vue.prototype.$api = api) in my main.js file, and then overwrite the global with a stub before each test.

describe('UploadForm.vue', () => {
  let wrapper;
  const uploadFile = sinon.stub().returns(Promise.resolve({ data: 0 }));
  beforeEach(() => {
    wrapper = mount(UploadForm, {
      globals: {
        $api: { uploadFile }
      }
    });
  });
  // ...

Leave a comment