详解Jest结合Vue-test-utils使用的初步实践

2020-06-14 06:26:38易采站长站整理

在如此修改后,测试通过,handler方法正确执行

同一个方法的多次mock

在一个组件中,我们可能会多次用到同一个外部的方法,但是每次返回值是不同的,我们可能要对它进行多次不同的mock

举个例子,在组件Test7中,mounted的时候forData返回一个数组,经过map处理后赋给text,点击getResult按钮,返回一个0或1的数字,根据返回值为result赋值


<template>
<div class="outer">
<p>{{text}}</p>
<p>Result is {{result}}</p>
<button @click="getResult">getResult</button>
</div>
</template>

<script>
import { forData } from '@/helper';
import axios from 'axios'

export default {
data() {
return {
text: '',
result: ''
}
},
async mounted() {
const ret = await forData(axios.get('text.do'));
this.text = ret.map(val => val.name)
},
methods: {
async getResult() {
const res = await forData(axios.get('result.do'));
switch (res) {
case 0 : {
this.result = '000';
break
}
case 1 : {
this.result = '111';
break
}
}
},
}
}
</script>

针对getResult方法编写单元测试,针对两种返回值编写了两个用例,在用例中将forData方法mock掉,返回值是一个Promise值,再根据给定的返回值,判断结果是否符合预期:


describe('Test for Test7 Component', () => {
let wrapper;

beforeEach(() => {
wrapper = shallow(Test7);
});

afterEach(() => {
wrapper.destroy()
});

it('test for getResult', async () => {
// 设定forData返回值
const mockResult = 0;
const mockFn = jest.fn(() => (Promise.resolve(mockResult)));
helper.forData = mockFn;

// 执行
await wrapper.vm.getResult();
// 断言
expect(mockFn).toHaveBeenCalledTimes(1);
expect(wrapper.vm.result).toBe('000')
});

it('test for getResult', async () => {
// 设定forData返回值
const mockResult = 1;
const mockFn = jest.fn(() => (Promise.resolve(mockResult)));
helper.forData = mockFn;

// 执行
await wrapper.vm.getResult();
// 断言
expect(mockFn).toHaveBeenCalledTimes(1);
expect(wrapper.vm.result).toBe('111')
})
});

运行测试用例,虽然测试用例全部通过,但是控制台仍然报错了:

(node:17068) UnhandledPromiseRejectionWarning: TypeError: ret.map is
not a function

为什么呢?

原因就是在于,在第一个用例运行之后,代码中的forData方法被我们mock掉了,所以在运行第二个用例的时候,执行mounted的钩子函数时,forData返回值就是我们在上个用例中给定的1,所以使用map方法会报错