前端测试(Vue)

打印 上一主题 下一主题

主题 1641|帖子 1641|积分 4923

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?立即注册

x
Jset

支持断言、异步支持、Mock,代码覆盖率、开箱即用、Fast


  1. test("name",()=>{
  2.     expect(2+2).toBe(4)
  3.     expect(2+2).not.toBe(5 )
  4. })
复制代码
  1. const fetchuser = (cb) => {
  2.   setTimeout(() => {
  3.     cb("user");
  4.   }, 100);
  5. };
  6. it("testCB", (done) => {
  7.   fetchuser((value) => {
  8.     expect(value).toBe("user");
  9.     done();
  10.   });
  11. });
  12. const userPromise = Promise.resolve("aa");
  13. it("testPromise", () => {
  14.   return userPromise.then((value) => {
  15.     expect(value).toBe("aa");
  16.   });
  17. });
  18. it("testAsync", async () => {
  19.   const value = await userPromise;
  20.   expect(value).toBe("aa");
  21. });
  22. it("test with expect",()=>{
  23.     return expect(userPromise()).resolves.toBe('aa')
  24. })
复制代码
  1. const axios = require("axios");
  2. jest.mock("axios"); //接管axios模块
  3. axios.get.mockImplementation(() => {
  4.   return Promise.resolve({ data: "hello world" });
  5. });
  6. it("test with mock function", () => {
  7.   const mockCb = jest.fn(); //模拟一个函数、环境、参数等
  8.   mockTest(true, mockCb);
  9.   expect(mockCb).toHaveBeenCalled();
  10.   expect(mockCb).toHaveBeenCalledTimes(1);
  11.   expect(mockCb).toHaveBeenCalledWith("hello world");
  12. });
  13. const loopFetchuser=(cb)=>{
  14.     setTimeout(()=>{
  15.         cb("aa")
  16.         setTimeout(()=>{
  17.             cb("hello world")
  18.         },100)
  19.     },100)
  20. }
  21. jest.useFakeTimers() //接管setTimeout
  22. it("test looptimeout", () => {
  23.     const callback=jest.fn()
  24.     loopFetchuser(callback)
  25.     expect(callback).toHaveBeenCalledTimes()
  26.     jest.runAllTimers() //运行所有定时器,待所有定时器执行完成
  27.     expect(callback).toHaveBeenCalledTimes(2) //调用次数
  28. })
  29. it("test looptimeout", () => {
  30.     const callback=jest.fn()
  31.     loopFetchuser(callback)
  32.     expect(callback).toHaveBeenCalledTimes()
  33.     jest.runOnlyPendingTimes() //运行第一次调用的定时器
  34.     expect(callback).toHaveBeenCalledTimes(1) //调用次数
  35.     //处理
  36.     expect(callback).toHaveBeenCalledTimes() //运行第二次的定时器
  37.     expect(callback).toHaveBeenCalledTimes(2) //调用次数
  38. })
  39. //控制时间
  40. it("test looptimeout", () => {
  41.     const callback=jest.fn()
  42.     loopFetchuser(callback)
  43.     jest.advanceTimersByTime(100) //前进100ms
  44.     expect(callback).toHaveBeenCalledTimes(1) //调用次数
  45.     jest.advanceTimersByTime(50)
  46.     expect(callback).toHaveBeenCalledTimes(2) //err未到达第二次执行时间 //调用次数
  47. })
复制代码
Vue Test Utils

手动配置太过繁琐、我们可以使用插件,注意项目基于vue-cli  、、vue add unit-jest
简单测试
  1. import { shallowMount, mount } from '@vue/test-utils';
  2. import flushPromise from 'flush-promises';
  3. import HelloWorld from '@/components/HelloWorld.vue';
  4. import axios from 'axios';
  5. jest.mock('axios');
  6. const MockAxios = axios as jest.Mocked<typeof axios>;
  7. describe('HelloWorld.vue', () => {
  8.         it('renders props.msg when passed', () => {
  9.                 const msg = 'new message';
  10.                 const wrapper = shallowMount(HelloWorld, {
  11.                         props: { msg }
  12.                 }); //挂载一个组件 shallowMount 浅层挂载也就是只渲染组件本身,子组件不管
  13.                 console.log(wrapper.html());
  14.                 console.log(wrapper.get('h1').text()); //获取组件的h1标签的内容
  15.                 console.log(wrapper.find('h1').text()); //不返回error 找不到返回一个空对象
  16.                 //fingComponent 找到组件,可以传入一个组件对象查找
  17.                 console.log(wrapper.findComponent({ name: 'HelloWorld' }).exists()); //判断组件是否存在.props()获取组件的props
  18.                 it('renders props.msg when passed', async () => {
  19.                         const msg = 'new message';
  20.                         const wrapper = mount(HelloWorld, {
  21.                                 props: { msg }
  22.                         });
  23.                         await wrapper.get('button').trigger('click');
  24.                         expect(wrapper.get('button').text()).toBe('2');
  25.                         //验证表单
  26.                         await wrapper.get('input').setValue('hello');
  27.                         expect(wrapper.get('input').element.value).toBe('hello');
  28.                         await wrapper.get('button').trigger('click');
  29.                         expect(wrapper.get('.addTodo').text()).toBe('3');
  30.                         //验证emit是否发送
  31.                         expect(wrapper.emitted()).toHaveProperty('add');
  32.                         const events = wrapper.emitted('add');
  33.                         expect(events[0][0]).toEqual({ text: 'hello', id: 3 });
  34.                 });
  35.                 //跳过其他测试,只跑这一个
  36.                 it.only('mock axios', async () => {
  37.                         MockAxios.get.mockResolvedValue({ data: { msg: 'hello' } });
  38.                         wrapper.get('.loading').exists().toBeTruthy();
  39.                         await flushPromise(); //等待异步操作完成,界面更新完毕
  40.                         wrapper.get('.loading').exists().toBeFalsy();
  41.                         expect(wrapper.get('.msg').text()).toBe('hello');
  42.                 });
  43.         });
  44. });
复制代码
ant-design-vue和复杂单页面
  1. import { mount, VueWrapper } from '@vue/test-utils';
  2. import UserProfile from './UserProfile.vue';
  3. import { message } from 'ant-design-vue';
  4. import store from '@/store';
  5. let wrapper: VueWrapper<any>;
  6. const mockedRoutes: string[] = ['/login'];
  7. jest.mock('vue-router', () => ({
  8.         useRouter: () => ({
  9.                 push: (url: string) => mockedRoutes.push(url)
  10.         })
  11. }));
  12. jest.mock('ant-design-vue', () => ({
  13.         message: {
  14.                 success: jest.fn()
  15.         }
  16. }));
  17. const mockTemplate = {
  18.         template: '<div><slot></slot></div>'
  19. };
  20. const mockTemplate2 = {
  21.         template: '<div><slot></slot><slot name="overlay"></slot></div>'
  22. };
  23. const globalComponent = {
  24.         'a-button': mockTemplate,
  25.         'a-dropdown-button': mockTemplate2
  26. };
  27. describe('UserProfile.vue', () => {
  28.         beforeEach(() => {
  29.                 jest.useFakeTimers();
  30.                 wrapper = mount(
  31.                         UserProfile,
  32.                         {
  33.                                 props: {
  34.                                         user: { isLogin: false }
  35.                                 }
  36.                         },
  37.                         {
  38.                                 global: {
  39.                                         components: globalComponent,
  40.                                         provide: {
  41.                                                 store
  42.                                         }
  43.                                 }
  44.                         }
  45.                 );
  46.         });
  47.         it('is a Vue instance', async () => {
  48.                 await wrapper.get('div').trigger('click');
  49.                 expect(message).toHaveBeenCalled(); // 希望调用message.success
  50.                 expect(store.state.user.isLogin).toBe(true); // 希望store.state.user.isLogin为true
  51.         });
  52.         it('is a Vue instance', () => {
  53.                 expect(wrapper.get('div').text()).toBe('登录'); //希望有包含登录的div
  54.         });
  55.         it('is a Vue instance', async () => {
  56.                 await wrapper.setProps({ user: { isLogin: true, username: '用户名' } });
  57.                 expect(wrapper.get('.userProfileComponent').html()).toContain('用户名'); //希望有包含用户名 的div
  58.                 expect(wrapper.find('.userProfile-deopdown').exists()).toBeTruthy(); //希望存在登出按钮
  59.         });
  60.         it('ccc', async () => {
  61.                 await wrapper.get('.user div').trigger('click');
  62.                 expect(store.state.user.isLogin).toBe(true);
  63.                 expect(message.success).toHaveBeenCalled(); // 希望调用message.success
  64.                 jest.runAllTimers();
  65.                 expect(mockedRoutes).toEqual('/');
  66.         });
  67.         afterEach(() => {
  68.                 (message as jest.Mocked<typeof message>).success.mockReset();
  69.         });
  70. });
复制代码
 单测-store
  1. import store from '@/store/index'
  2. import { testData } from '@/store/templates'
  3. // import { testComponents, ComponentData } from '@/store/editor'
  4. import { clone, last } from 'lodash-es'
  5. // import { textDefaultProps } from 'lego-bricks'
  6. const cloneComponents = clone(testComponents)
  7. jest.mock('ant-design-vue')
  8. describe('test vuex store', () => {
  9.   it('should have three modules', () => {
  10.     expect(store.state).toHaveProperty('user')
  11.     expect(store.state).toHaveProperty('templates')
  12.     expect(store.state).toHaveProperty('editor')
  13.   })
  14.   describe('test user module', () => {
  15.     it('test login mutation', () => {
  16.       store.commit('login')
  17.       expect(store.state.user.isLogin).toBeTruthy()
  18.     })
  19.     it('test logout mutation', () => {
  20.       store.commit('logout')
  21.       expect(store.state.user.isLogin).toBeFalsy()
  22.     })
  23.   })
  24.   describe('test templates module', () => {
  25.     it('should have default templates', () => {
  26.       expect(store.state.templates.data).toHaveLength(testData.length)
  27.     })
  28.     it('should get the correct template by Id', () => {
  29.       const selectTemplate = store.getters.getTemplateById(1)
  30.       expect(selectTemplate.title).toBe('test title 1')
  31.     })
  32.   })
  33. })
复制代码
TDD

测试驱动开辟


免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
回复

举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

民工心事

论坛元老
这个人很懒什么都没写!
快速回复 返回顶部 返回列表