<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>
详解Jest结合Vue-test-utils使用的初步实践(13)
针对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方法会报错
为了解决这个问题,我们需要在beforeEach(或afterEach)中,重置forData的状态,如果在代码中使用了MockJS的情况下,我们只需要让默认的forData获取的数据走原来的路径,由MockJS提供假数据即可,这样我们只需要在一代码的最开始将forData保存,在beforeEach使用restoreAllMocks方法重置状态,然后在恢复forData状态,然后每个用例中针对forData进行单独的mock即可
const test = helper.forData; describe('Test for Test7 Component', () => { let wrapper; beforeEach(() => { jest.restoreAllMocks(); helper.forData = test; wrapper = shallow(Test7); }); afterEach(() => { wrapper.destroy() }); // 用例不变
内容版权声明:除非注明,否则皆为本站原创文章。