使用 avoriaz 挂载 vue 实例,但 sinon 无法监视导入的函数
Mounting a vue instance with avoriaz, but cannot sinon spy on imported function
我有以下组件脚本(删除了一些不相关的位):
import api from '@/lib/api';
export default {
methods: {
upload (formData) {
api.uploadFile(formData).then(response => {
this.$emit('input', response.data);
});
}
}
};
我有以下测试,它使用 avoriaz 挂载 Vue 实例:
import { mount } from 'avoriaz';
import { expect } from 'chai';
import sinon from 'sinon';
import UploadForm from '@/components/UploadForm';
describe('upload', () => {
it('passes form data to api.uploadFile', () => {
const testFormData = { test: 'test' };
const api = {
uploadFile: sinon.spy()
};
const wrapper = mount(UploadForm);
wrapper.vm.api = api;
wrapper.vm.upload(testFormData);
expect(api.uploadFile.called).to.equal(true);
});
});
我的 sinon 间谍从来没有被调用过,我已经尝试了上面的几个不同的变体。监视这样的导入函数的最佳方法是什么?还是我在概念上以错误的方式接近了这个?
问题
你需要stub api 依赖,这是文件的依赖。这不能通过 vue 实例完成,因为 api 不是 vue 组件的一部分。
您需要存根文件依赖项。
解决方案
一种方法是使用 inject-loader
.
步骤
安装注入加载器
npm install --save-dev inject-loader
在文件的顶部,导入 UploadForm
with inject-loader
和 vue-loader
:
import UploadFormFactory from '!!vue-loader?inject!@/components/UploadForm';
这是一个工厂函数,returns UploadForm
已删除依赖项。
现在,在您的测试中,您需要调用 UploadFormFactory
以及您想要存根的依赖项:
const api = {
uploadFile: sinon.spy()
};
const UploadForm = UploadFormFactory({
'@/lib/api': api
})
因此您的测试文件将如下所示:
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);
});
});
更多信息
我在这里写了一个更详细的教程 - https://www.coding123.org/stub-dependencies-vue-unit-tests/
我认为 Edd 的回答对于大多数情况来说是最全面的,所以我将他的回答标记为已接受的回答。但是,我想出的解决方法是在我的 main.js 文件中将 api 库设为全局服务 (Vue.prototype.$api = api
),然后在每次测试前用存根覆盖全局。
describe('UploadForm.vue', () => {
let wrapper;
const uploadFile = sinon.stub().returns(Promise.resolve({ data: 0 }));
beforeEach(() => {
wrapper = mount(UploadForm, {
globals: {
$api: { uploadFile }
}
});
});
// ...
我有以下组件脚本(删除了一些不相关的位):
import api from '@/lib/api';
export default {
methods: {
upload (formData) {
api.uploadFile(formData).then(response => {
this.$emit('input', response.data);
});
}
}
};
我有以下测试,它使用 avoriaz 挂载 Vue 实例:
import { mount } from 'avoriaz';
import { expect } from 'chai';
import sinon from 'sinon';
import UploadForm from '@/components/UploadForm';
describe('upload', () => {
it('passes form data to api.uploadFile', () => {
const testFormData = { test: 'test' };
const api = {
uploadFile: sinon.spy()
};
const wrapper = mount(UploadForm);
wrapper.vm.api = api;
wrapper.vm.upload(testFormData);
expect(api.uploadFile.called).to.equal(true);
});
});
我的 sinon 间谍从来没有被调用过,我已经尝试了上面的几个不同的变体。监视这样的导入函数的最佳方法是什么?还是我在概念上以错误的方式接近了这个?
问题
你需要stub api 依赖,这是文件的依赖。这不能通过 vue 实例完成,因为 api 不是 vue 组件的一部分。
您需要存根文件依赖项。
解决方案
一种方法是使用 inject-loader
.
步骤
安装注入加载器
npm install --save-dev inject-loader
在文件的顶部,导入 UploadForm
with inject-loader
和 vue-loader
:
import UploadFormFactory from '!!vue-loader?inject!@/components/UploadForm';
这是一个工厂函数,returns UploadForm
已删除依赖项。
现在,在您的测试中,您需要调用 UploadFormFactory
以及您想要存根的依赖项:
const api = {
uploadFile: sinon.spy()
};
const UploadForm = UploadFormFactory({
'@/lib/api': api
})
因此您的测试文件将如下所示:
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);
});
});
更多信息
我在这里写了一个更详细的教程 - https://www.coding123.org/stub-dependencies-vue-unit-tests/
我认为 Edd 的回答对于大多数情况来说是最全面的,所以我将他的回答标记为已接受的回答。但是,我想出的解决方法是在我的 main.js 文件中将 api 库设为全局服务 (Vue.prototype.$api = api
),然后在每次测试前用存根覆盖全局。
describe('UploadForm.vue', () => {
let wrapper;
const uploadFile = sinon.stub().returns(Promise.resolve({ data: 0 }));
beforeEach(() => {
wrapper = mount(UploadForm, {
globals: {
$api: { uploadFile }
}
});
});
// ...