Jest单元测试 cors TS

一、例子

utils/cal.js

export const sum = (x, y) => {
  return x + y
}

export const subtract = (x, y) => {
  return x - y
}

import { sum } from '@/utils/cal'

const result = 3

const actual = sum(1, 2)

if (actual === result) { 
  console.log('测试通过')
} else { 
  console.log(`测试失败:1 + 2 期望得到${result},但是得到了${actual}`)
}

断言函数封装

import { sum, subtract } from '@/utils/cal'
expect(sum(1,2)).toBe(3) // 断言

function expect(actual) {
  return {
    toBe(result) {
      if (actual !== result) {
        console.log('测试失败')
      } else { 
        console.log('测试通过')
      }
    }
  }
}
import { sum, subtract } from '@/utils/cal'

test('sum', () => { // 测试用例
  expect(sum(1, 2)).toBe(3) // 断言
})

test('subtract', () => { // 测试用例
  // toBe 相等匹配
  expect(subtract(2, 1)).toBe(1) // 断言
})


function test(message, callback) {
  try { 
    callback()
  } catch (e) {
    console.log(`${message}:${err.message}`)
  }
}

function expect(actual) {
  return {
    toBe(result) {
      if (actual !== result) {
        console.log('测试失败')
      } else { 
        console.log('测试通过')
      }
    }
  }
}

二、Jest

官网:https://jestjs.io

vue test util
https://vue-test-utils.vuejs.org/zh/guides/#%E5%B8%B8%E7%94%A8%E6%8A%80%E5%B7%A7

1、测试标题

test('标题的内容是 todos', () => {
  const wrapper = mount(TodoApp)
  // console.log(wrapper.find('h1').text())
  expect(wrapper.find('h1').text()).toBe('todos')
})

2、测试列表长度

test('任务列表展示正常', async () => {
  // 给定一份测试数据
  const wrapper = shallowMount(TodoApp)

  // 准备测试数据
  wrapper.vm.todos = [
    { id: 1, text: 'eat', done: true },
    { id: 2, text: 'sleep', done: true },
    { id: 3, text: 'play', done: false }
  ]

  // 等待视图更新
  await Vue.nextTick()

  // 测试:期望页面中的 dom 元素和数据是匹配的
  // console.log(wrapper.findAll('[data-testid="todo-item"]').length)
  // console.log(wrapper.vm.todos.length)
  expect(wrapper.findAll('[data-testid="todo-item"]').length).toBe(wrapper.vm.todos.length)
})

3、添加任务

test('添加任务正常', async () => {
  // 给定一份测试数据
  const text = 'hello'
  const wrapper = shallowMount(TodoApp)
  const input = wrapper.find('[data-testid="new-todo"]')
  // 给 input 输入内容
  await input.setValue(text) // 内部集成了 nextTick
  // 触发回车事件
  await input.trigger('keyup.enter') // 等待事件触发,视图数据更新

  // 断言:列表中多出了一个内容为 hello 的 todo-item
  const list = wrapper.findAll('[data-testid="todo-text"]')
  const last = list.at(list.length - 1)
  expect(last.text()).toBe(text)

  // console.log(input.element.value)
  expect(input.element.value).toBe('')
  // expect(input)
})

test('标题的内容是 todos', () => {
  const wrapper = mount(TodoApp)
  // console.log(wrapper.find('h1').text())
  expect(wrapper.find('h1').text()).toBe('todos')
})

三、cors解决跨域

const express = require('express')
const cors = require('cors')

const app = express()
const port = 3000

// 服务端设置:开启 CORS 跨域资源请求处理,客户端什么也不用做
// app.use(cors({
//   // origin: '*',
//   origin: 'http://localhost:5501'
// }))

app.get('/', (req, res) => {
  // 设置 HTTP 响应头
  // res.setHeader('Access-Control-Allow-Origin', '*')
  res.send('Hello World!')
})

app.listen(port, () => {
  console.log(`Example app listening at http://localhost:${port}`)
})

四、中间层

和客户端一样,服务器也可以发请求,因为不是浏览器,所以服务端的请求没有同源策略限制

  http.request('http://localhost:3000', res => {
    let data = []
    res.on('data', (chunk) => {
      data.push(chunk)
    })
    res.on('end', () => {
      console.log(data.toString())
    })
  })

五、TS

import request from '@/utils/request'

interface User {
  email: string
  password: string
}

export interface UserRes {
  email: string
  token: string
  username: string
  bio: string
  image: string
}

interface LoginInput {
  user: User
}

interface LoginData {
  user: UserRes
}

export const login = (data: LoginInput) => {
  // axios 中的 get、post、delete、put 等请求方法都支持通过泛型指定返回的 data 类型
  return request.post<LoginData>('/api/users/login', data)
}

interface RegisterInput {
  user: {
    username: string
    email: string
    password: string
  }
}

interface RegisterData {
  user: UserRes
}

export const register = (data: RegisterInput) => {
  return request.post<RegisterData>('/api/users/login', data)
}

login.vue

<template>
  <div class="auth-page">
    <div class="container page">
      <div class="row">
        <div class="col-md-6 offset-md-3 col-xs-12">
          <h1 class="text-xs-center">Sign up</h1>
          <p class="text-xs-center">
            <a href="">Have an account?</a>
          </p>

          <ul class="error-messages">
            <li>That email is already taken</li>
          </ul>

          <form @submit.prevent="handleSubmit">
            <!-- <fieldset class="form-group">
              <input
                class="form-control form-control-lg"
                type="text"
                placeholder="Your Name"
              />
            </fieldset> -->
            <fieldset class="form-group">
              <input
                class="form-control form-control-lg"
                type="text"
                v-model="user.email"
                placeholder="Email"
              />
            </fieldset>
            <fieldset class="form-group">
              <input
                v-model="user.password"
                class="form-control form-control-lg"
                type="password"
                placeholder="Password"
              />
            </fieldset>
            <button class="btn btn-lg btn-primary pull-xs-right">
              Sign up
            </button>
          </form>
        </div>
      </div>
    </div>
  </div>
</template>

<script lang="ts">
import { defineComponent, reactive } from 'vue'
import { login } from '@/api/user'
import { useRouter } from 'vue-router'
// import { useStore } from 'vuex'
// import { key } from '@/store'
import { useStore } from '@/store'

const useLogin = () => {
  const router = useRouter() // 获取当前路由对象
  const store = useStore()

  // Composition API 中没有 this
  const user = reactive({
    email: '',
    password: ''
  })

  const handleSubmit = async () => {
    try {
      const { data } = await login({
        user
      })

      console.log('登录成功', data)

      store.commit('setUser', {
        user: data.user
      })

      // console.log(store.state.user)

      // 登录成功,跳转到首页
      router.push({
        name: 'home'
      })
    } catch (err) {
      console.log('登录失败', err)
    }
  }

  return {
    user,
    handleSubmit
  }
}

export default defineComponent({
  name: 'LoginPage',
  setup () {
    return {
      ...useLogin()
    }
  }
})
</script>

store

import { InjectionKey } from 'vue'
import { createStore, Store, useStore as baseUseStore, createLogger } from 'vuex'
import { UserRes } from '@/api/user'

// define your typings for the store state
export interface State {
  count: number
  user: UserRes | null
}

// define injection key
export const key: InjectionKey<Store<State>> = Symbol('store')

// new Vuex.Store({ state... })
export const store = createStore<State>({
  state: {
    count: 0,
    user: null
  },
  mutations: {
    setUser (state, payload) {
      state.user = payload.user
    }
  },
  actions: {
  },
  modules: {
  },
  plugins: [createLogger()]  // 控制台打印插件
})

// define your own `useStore` composition function
export function useStore () {
  // 这里调用真正的 useStore
  return baseUseStore(key)
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Jest 是一个流行的 JavaScript 测试框架,可以用于编写单元测试、集成测试和端到端测试。下面是 Jest 单元测试入门的步骤: 1. 安装 Jest 使用 npm 安装 Jest:`npm install --save-dev jest` 2. 编写测试用例 在项目根目录下创建一个名为 `__tests__` 的文件夹,并在其中创建一个名为 `example.test.js` 的文件。在 `example.test.js` 文件中编写测试用例: ```javascript describe('示例测试', () => { test('测试1', () => { expect(1 + 1).toBe(2); }); test('测试2', () => { expect(true).toBeTruthy(); }); }); ``` 上面的代码定义了一个测试套件 `示例测试`,其中包含两个测试用例 `测试1` 和 `测试2`。每个测试用例都是一个函数,其中包含一个或多个 `expect` 语句,用于断言测试结果是否符合预期。 3. 运行测试 在命令行中输入 `npx jest` 命令,Jest 将自动查找项目中的测试用例并运行它们。如果所有测试用例都通过,Jest 将输出一个绿色的提示。 4. 高级配置 Jest 提供了丰富的配置选项,可以用于定制测试过程。例如,可以在 `package.json` 文件中添加以下配置: ```json { "jest": { "testEnvironment": "node", "testMatch": [ "**/__tests__/**/*.test.js" ], "coverageThreshold": { "global": { "branches": 80, "functions": 80, "lines": 80, "statements": 80 } } } } ``` 上面的配置指定了测试环境为 Node.js,测试文件必须位于 `__tests__` 文件夹中,并以 `.test.js` 结尾。还指定了代码覆盖率的阈值,如果代码覆盖率低于指定的阈值,Jest 将会提示测试失败。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值