Vitest 单元测试

这篇具有很好参考价值的文章主要介绍了Vitest 单元测试。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

一、自动化测试(TDD)的一些概念:

自动化测试(TDD)概念:

自动化测试是指 使用独立于待测软件的其他软件或程序来自动执行测试,比较实际结果与预期 并生成测试报告这一过程。在测试流程已经确定后,测试自动化可以自动执行的一些重复性但必要的测试工作。也可以完成手动测试几乎不可能完成的测试。

自动化测试分类:

1. 基于图形用户交互界面测试

基于用户界面(GUI)的测试使用能够产生图形用户界面操作(如出表点击、键盘输入等)的测试框架,模拟用户动作来以观察、验证程序是否正确的响应。

2. 接口测试

接口测试指的是通过调用接口(API)绕过GUI层,以 API 应用验证行为进行测试。通常API 绕过测试的应用程序的用户界面。它也可以测试 公共(通常)的接口 ,用各种各样的输入参数来验证返回的结果是正确的。

自动化测试有什么意义

1、单元测试的用例可以在代码编写完成之前就设计好,并作为功能的一种定义形式存在。随着新的代码不断完成编写,单元测试随之进行,缺陷被不断找出,因而代码也不断得到改进。

2、手工完成一些软件测试的工作(例如大量的低级接口的回归测试)十分艰苦耗时, 而且寻找某些种类的缺陷时效率并不高,因而测试自动化,提供一种完成这类工作的有效方法。

3、一旦自动化测试方法开发完成,日后的测试工作将可以高效循环完成。很多时候这是针对软件产品进行长期回归测试的高效方法。毕竟早期一个微小的补丁中引入的回归问题可能在日后导致巨大的损失。

前端自动化测试(基于图形用户交互界面测试GUI)有哪些:

1. 单元测试

把代码看成一个个组件,对每个组件进行单独测试,组件内每一个函数的返回结果(或者dom的结构)是不是和期望值一样。

2. e2e(端到端)测试

把程序当做黑盒子,以用户的视角对真实系统的访问行为进行仿真,对测试的输入(用户行为/模拟数据),看能否得到预期得到的结果。

二、Vitest介绍及与其它框架对比

1、什么是Vitest

vitest是由vite提供支持的下一代测试框架

该工具一开始就考虑到了vite,利用了在DX中的改进,例如即时热模块重新加载(HMR)

由 Vite 提供支持的极速原生的单元测试框架。安装 pnpm add -D vitest,Vitest 需要 Vite >=v3.0.0 和 Node >=v14。

  1. Vite 支持
    重复使用 Vite 的配置、转换器、解析器和插件 - 在您的应用程序和测试中保持一致。

  2. 兼容 Jest
    拥有预期、快照、覆盖等 - 从 Jest 迁移很简单。

  3. 智能即时浏览模式
    智能文件监听模式,就像是测试的 HMR!

  4. ESM, TypeScript, JSX
    由 esbuild 提供的开箱即用 ESM、TypeScript 和 JSX 支持。

2、vite的目标

定位为vite项目的首选测试运行者,甚至对于不使用vite的项目来说也是一个可靠的替代方案

3、vitest和其他测试框架的比较

3.1 Jest vs Vitest

Jest

  • 接管了测试框架领域,jest团队和社区创建了很多测试API,并推动了许多测试模式,这些模式已经成为了web生态系统的标准

Vitest

  • 你的项目没有使用vite:提供大多数与jest的api和生态系统的兼容性,可以让你更快地运行单元测试,在大多数项目中,是Jest的直接替代品
  • 你的项目使用vite:如果使用Jest,那么需要配置和维护两个不同的管道,这是不合理的,如果使用vitest,那么您可以将开发,构建,测试环境的配置定义为单个管道,共享相同的插件和相同的vite.config.js,避免了重复性的麻烦

3.2、Cypress vs Vitest

cypress 定义

被称为端到端测试工具,其新组件测试运行期对测试vite有很大的支持,并且·是测试浏览器中呈现的内容的理想选择
 
是基于浏览器的测试运行期,是vite的补充工具,将捕获vitest无法捕获的问题(因为其使用真实的浏览器和真实的浏览器api)

vitest定义

是基于节点的运行程序,专注于为闪电般的无头测试提供最佳DX,

cypress 功能

用于e2e和组件测试


其测试驱动恒旭专注于确定元素是否可见,可访问,交互,cypress专为UI开发和测试而构建,测试完成之后,您可以使用浏览器开发工具调试发生的任何故障
 
像IDE,您可以在浏览器中看到真实渲染的组件以及测试结果和日志


vitest 功能

用于单元测试(测试无头代码的好选择)
 
支持各种部分实现的浏览器环境,例如Jsdom,这些环境足以让您快速对引用浏览器api的任何代码进行单元测试,代价是这些浏览器环境在其可实现的功能方面存在限制,例如jsdom缺少很多功能(window.navigation,布局引擎offsetTop)
使用

对应用程序中的所有无头逻辑使用vitest,对所有基于浏览器的逻辑使用cypress
 

三、vitest 相关

1、测试环境 environment

Vitest 提供 environment 选项以在特定环境中运行代码,可以使用 environmentOptions 选项修改环境的行为方式。默认情况下,可以使用这些环境:

  • node 为默认环境
  • jsdom 通过提供 Browser API 模拟浏览器环境,使用 jsdom 包
  • happy-dom 通过提供 Browser API 模拟浏览器环境,被认为比 jsdom 更快,但缺少一些 API,使用 happy-dom 包
  • edge-runtime 模拟 Vercel 的 edge-runtime,使用 @edge-runtime/vm 包
  1. 设置 environment 选项时,它将应用于项目中的所有测试文件。要获得更细粒度的控制,可以使用控制注释为特定文件指定环境,以 @vitest-environment 开头,后跟环境名称的注释:
// @vitest-environment jsdom

import { test } from 'vitest'

test('test', () => {
  expect(typeof window).not.toBe('undefined')
})

也可以通过设置 environmentMatchGlobs 选项,根据 glob 模式指定环境。

Vitest 单元测试,单元测试

2、测试上下文

Vitest 的测试上下文允许你定义可在测试中使用的工具(utils)、状态(states)和固定装置(fixtures)。

1、每个测试回调的第一个参数是测试上下文。

import { it } from 'vitest'

it('should work', (ctx) => {
  // prints name of the test
  console.log(ctx.meta.name)
})

2、内置的测试上下文。

  • context.meta
    包含关于测试的元数据的只读对象。
  • context.expect
    绑定到当前测试的 expect API。

3、每个测试的上下文都不同。可以在 beforeEach 和 afterEach hooks 中访问和扩展它们。

import { beforeEach, it } from 'vitest'

beforeEach(async (context) => {
  // extend context
  context.foo = 'bar'
})

it('should work', ({ foo }) => {
  console.log(foo) // 'bar'
})

4、可以通过添加聚合(aggregate)类型 TestContext, 为你的自定义上下文属性提供类型支持。

declare module 'vitest' {
  export interface TestContext {
    foo?: string
  }
}

如果只想为特定的 beforeEachafterEachit 或 test hooks 提供属性类型,则可以将类型作为泛型传递。

interface LocalTestContext {
  foo: string
}

beforeEach<LocalTestContext>(async (context) => {
  // typeof context is 'TestContext & LocalTestContext'
  context.foo = 'bar'
})

it<LocalTestContext>('should work', ({ foo }) => {
  // typeof foo is 'string'
  console.log(foo) // 'bar'
})

3、扩展断言

  1. 可以使用对象包裹断言的形式调用 expect.extend 方法扩展默认的断言。
expect.extend({
  // 第一个参数是接收值,其余参数将直接传给断言
  toBeFoo(received, expected) {
    const { isNot } = this
    return {
      // 请勿根据 isNot 参数更改你的 "pass" 值,Vitest 为你做了这件事情
      pass: received === 'foo',
      message: () => `${received} is${isNot ? ' not' : ''} foo`,
    }
  },
})

测试案例:

import { describe, it, expect } from 'vitest'

expect.extend({
  // 第一个参数是接收值,其余参数将直接传给断言
  toBeFoo(received, expected) {
    const { isNot,promise } = this;
    return {
      // 请勿根据 isNot 参数更改你的 "pass" 值,Vitest 为你做了这件事情
      pass: received === 'foo',
      message: () => `${received} is${isNot ? ' not' : ''} foo`,
    }
  },
})

it('扩展断言', () => {
  expect('foo1').not.toBeFoo();
  expect('foo').toBeFoo();
})

断言方法可以访问上下文 this 对象中的这些属性:

  • isNot
    如果断言是在 not 方法上调用的( expect(received).not.toBeFoo() ),则返回 true
  • promise
    如果断言是在 resolved/rejected 中调用的,它的值将包含此断言的名称。否则,它将是一个空字符串。
  • equals
    这是一个工具函数,他可以帮助你比较两个值。如果是相同的则返回 true,反之返回 false。这个方法几乎在每个断言内部都有使用。默认情况下,它支持非对称的断言。
  • utils
    它包含了一系列工具函数,可以使用它们来显示信息。

this 上下文也包含了当前测试的信息,可以通过调用 expect.getState() 来获取它,有用的属性是:

  • currentTestName
    当前测试的全称(包括 describe 块)。
  • testPath
    当前测试的路径。

断言的返回值应该兼容如下接口:

interface MatcherResult {
  pass: boolean
  message: () => string
  // 如果你传了这些参数,它们将自动出现在 diff 信息中,
  // 所以即便断言不通过,你也不必自己输出 diff
  actual?: unknown
  expected?: unknown
}

4、源码内联测试

Vitest 还提供了一种方式,可以运行与你的代码实现放在一起的测试,允许测试与实现共享相同的闭包,并且能够在不导出的情况下针对私有状态进行测试。可用于:

  • 小范围的功能或工具的单元测试
  • 原型设计
  • 内联断言 对于更复杂的测试,比如组件测试或 E2E 测试,建议使用单独的测试文件取而代之

1、首先,在 if (import.meta.vitest) 代码块内写一些测试代码并放在文件的末尾,例如:

// src/index.ts

// 函数实现
export function add(...args: number[]) {
  return args.reduce((a, b) => a + b, 0)
}

// 源码内的测试套件
if (import.meta.vitest) {
  const { it, expect } = import.meta.vitest
  it('add', () => {
    expect(add()).toBe(0)
    expect(add(1)).toBe(1)
    expect(add(1, 2, 3)).toBe(6)
  })
}

2、更新 Vitest 配置文件内的 includeSource 以获取到 src/ 下的文件:

// vite.config.ts
import { defineConfig } from 'vitest/config'

export default defineConfig({
  test: {
    includeSource: ['src/**/*.{js,ts}'],
  },
})

3、执行测试

npx vitest

4、对于生产环境的构建,你需要设置配置文件内的 define 选项,让打包器清除无用的代码。

// vite.config.ts
import { defineConfig } from 'vitest/config'

export default defineConfig({
+ define: {
+   'import.meta.vitest': 'undefined',
+ },
  test: {
    includeSource: ['src/**/*.{js,ts}']
  },
})

5、要获得对 import.meta.vitest 的 TypeScript 支持,添加 vitest/importMeta 到 tsconfig.json

// tsconfig.json
{
  "compilerOptions": {
    "types": [
+     "vitest/importMeta"
    ]
  }
}

5、快照

当希望确保函数的输出不会意外更改时,可以使用快照测试,兼容 Jest 快照测试。使用快照时,Vitest 将获取给定值的快照,将其比较时将参考存储在测试旁边的快照文件。如果两个快照不匹配,则测试将失败:要么更改是意外的,要么参考快照需要更新到测试结果的新版本。

要将一个值快照,你可以使用 expect()toMatchSnapshot() API:

import { expect, it } from 'vitest'
it('renders correctly', () => {
  const result = toUpperCase('foobar')
  expect(result).toMatchSnapshot()
})

4、vitest配置

安装:

pnpm install -D vitest

package.json配置

 "test:unit": "vitest --typecheck",

 运行模式,运行或者监听

vitest watch      监听模式 为执行vitest的默认模式

vitest run   运行模式

可以直接在当前的vite.config.ts文件中配置

/// <reference types="vitest" />

...

  test: {

    globals:true, // 是否全局引入

    environment:"happy-dom" // 环境选择 jsdom

    // include: ['test/**/*.test.ts'],

    // deps: {

    //   inline: ['@vue', '@vueuse', 'element-plus', 'vue-i18n'],

    // },

  },

也可以单独创建一个vitest.config.ts文件,优先级高于vite.config.ts

import { fileURLToPath } from 'node:url'
import { mergeConfig, defineConfig, configDefaults } from 'vitest/config'
import viteConfig from './vite.config'
export default mergeConfig(
  viteConfig,
  defineConfig({
    define: {
      'import.meta.vitest': 'undefined', // 源码内联测试配置
    }, 
    test: {
      // 启用基准测试模式  
      mode: 'benchmark',  
      // globals: true, // 全局引入vitest 位置一
      environment: 'jsdom',
      exclude: [...configDefaults.exclude, 'e2e/*'],
      includeSource: ['src/**/*.{js,ts}'], 
      root: fileURLToPath(new URL('./', import.meta.url)),
      coverage: {
        provider: 'istanbul', // or 'v8'  默认使用v8
        reporter: ['text', 'html', 'json'],
        // reporters: ['verbose'],
        reporters: ['html'],
        // reportsDirectory: './tests/unit/coverage', // 修改输出报告位置
        exclude:['src/**/icons'] //不需要单元测试覆盖的地方
      },
      // browser: {
      //   enabled: true,
      //   name: 'chrome', // browser name is required
      // },
    }
  })
)

6、测试可过滤

当只需要运行某个测试文件,或者包含某字符串的测试文件

$ vitest basic

将只执行包含 basic 的测试文件,例如:

basic.test.ts
basic-foo.test.ts
basic/foo.test.ts

7、 .concurrent、.sequential

如果在测试套件中使用 .concurrent,则其中的每个测试用例都将并发运行。

你还可以将 .skip(跳过).only (仅执行这个)和 .todo (待完成)用于并发测试套件和测试用例。

sequential  按顺序测试

fails 明确表示断言失败

运行并发测试时,快照和断言必须使用本地测试上下文中的 expect,以确保检测到正确的测试。

test.concurrent("test 1", async ({ expect }) => {
  expect(foo).toMatchSnapshot();
});
test.concurrent("test 2", async ({ expect }) => {
  expect(foo).toMatchSnapshot();
}); 

8、快照

当希望确保函数的输出不会意外更改时,可以使用快照测试,兼容 Jest 快照测试。使用快照时,Vitest 将获取给定值的快照,将其比较时将参考存储在测试旁边的快照文件。如果两个快照不匹配,则测试将失败:要么更改是意外的,要么参考快照需要更新到测试结果的新版本。

// 此测试在第一次运行时,Vitest 会创建一个快照文件

expect(result).toMatchSnapshot()

// 内联快照  这允许你直接查看期望输出,而无需跨不同的文件跳转。expect(result).toMatchInlineSnapshot(`"FOOBAR"`)

// 文件快照会以文件的方式存储  

await expect(result).toMatchFileSnapshot('../__snapshots__/HelloWorld1.json') // 文件保存路径

自动更新内联快照内容:

 npx vitest -u

执行 npm run vitest 命令 不会更新内联快照

9、对象模拟(Mocking)

10、测试覆盖率

 npx vitest --coverage 输出覆盖范围

Vitest 通过 v8(默认) 支持原生代码覆盖率,通过 istanbul 支持检测代码覆盖率。

// vitest.config.ts
import { defineConfig } from 'vitest/config'

export default defineConfig({
  test: {
    coverage: {
      provider: 'istanbul', // or 'v8'
    },
  },
})

定义输出报告的格式

// vitest.config.ts
import { defineConfig } from 'vitest/config'

export default defineConfig({
  test: {
    coverage: {
      reporter: ['text', 'json', 'html'],
    },
  },
})

这个属性定义了覆盖率报告的输出格式。这里指定了三种格式:文本、JSON 和 HTML。这意味着在运行测试时,Vitest 将生成并输出这三种格式的覆盖率报告。

11、源码内联测试

// src/index.ts

// 函数实现
export function add(...args: number[]) {
  return args.reduce((a, b) => a + b, 0)
}

// 源码内的测试套件
if (import.meta.vitest) {
  const { it, expect } = import.meta.vitest
  it('add', () => {
    expect(add()).toBe(0)
    expect(add(1)).toBe(1)
    expect(add(1, 2, 3)).toBe(6)
  })
}

更新配置文件

// vite.config.ts
/// <reference types="vitest" />
import { defineConfig } from 'vite'

export default defineConfig({

 define: {

    'import.meta.vitest': 'undefined', // 源码内联测试配置

  },

  test: {
    includeSource: ['src/**/*.{js,ts}'], 
  },
})

12、ts类型测试

import { assertType, expectTypeOf ,test} from 'vitest'
import { mount } from '../../assets/common'

test('my types work properly', () => {
  expectTypeOf(mount).toBeFunction()
  expectTypeOf(mount).parameter(0).toMatchTypeOf<{ name: string }>() //  验证 mount 函数的第一个参数的类型是否为 { name: string }。
  // @ts-expect-error name is a string       // 这是一个注释,指示 TypeScript 在编译时应该期望一个错误,因为接下来的代码会尝试将一个非字符串值赋给 name。
  assertType(mount({ name: 42 })) // 尝试调用 mount 函数并传递一个对象作为参数,其中 name 的值是 42(一个数字,而不是字符串)。由于前面的注释,TypeScript 应该期望这里有一个类型错误。
})

说明​

此功能可用于:

  • 小范围的功能或 utils 工具的单元测试
  • 原型设计
  • 内联断言

对于更复杂的测试,比如组件测试或 E2E 测试,建议使用单独的测试文件取而代之

vitest 退出及时更新模式

npx vitest run

要重新打开Vitest的多线程功能,您需要移除--no-threads选项,然后再次运行测试。

例如,如果您之前使用以下命令禁用了多线程:

vitest --no-threads

要重新打开多线程功能,只需运行以下命令:

vitest

这将重新启用Vitest的多线程功能,并允许测试并行运行以提高执行效率。

请注意,禁用多线程功能可能会降低测试的执行效率,因为测试将按顺序逐个执行,而不是并行运行。在大多数情况下,建议使用多线程功能来提高测试的执行效率。

  1. assert(value, message):断言函数返回的值是否为真。如果断言失败,则抛出错误并显示提供的消息。
  2. toBe(value):断言函数返回的值是否严格等于给定的值。
  3. toBeCloseTo(value, precision):断言函数返回的值是否接近给定的值。precision 参数指定小数点后的位数。
  4. toBeDefined():断言函数返回的值是否已定义(不是 undefined)。
  5. toBeFalsy():断言函数返回的值是否为假值(false、null、undefined、0、NaN 或空字符串)。
  6. toBeGreaterThan(value):断言函数返回的值是否大于给定的值。
  7. toBeLessThan(value):断言函数返回的值是否小于给定的值。
  8. toBeNaN():断言函数返回的值是否为 NaN。
  9. toBeNull():断言函数返回的值是否为 null。
  10. toBeTruthy():断言函数返回的值是否为真值(true、非空对象、非零数字、非 NaN)。
  11. toBeUndefined():断言函数返回的值是否未定义(undefined)。
  12. toContain(element):断言函数返回的数组是否包含指定的元素。
  13. toEqual(value):断言函数返回的值是否与给定的值相等。
  14. toMatch(pattern):断言函数返回的值是否匹配正则表达式或字符串。

1、两种单元测试文件名.spec.ts文件和.test.ts的区别:

  • .spec.ts文件和.test.ts文件在软件开发中都用于编写测试代码,但它们之间存在一些关键的区别。
  • 首先,规范(spec)文件通常用于描述和验证行为,特别是在软件开发中。在Angular开发中,规范文件是用于编写单元测试和集成测试的脚本文件。这些文件扩展名为“spec.ts”,并且在Angular开发中,每个.ts文件都应对应一个.spec.ts文件。它们通过Karma测试运行程序(使用Jasmine JavaScript测试框架)来运行测试。
  • 另一方面,test.ts文件通常用于编写任何类型的测试代码,包括单元测试、集成测试等。这些文件扩展名为.ts,并且它们没有特定的命名约定或用途。它们可以用于任何需要测试的场合,包括但不限于软件开发。
  • 总的来说,.spec.ts文件和.test.ts文件之间的主要区别在于它们的用途和上下文。规范文件主要用于描述和验证行为,特别是在软件开发中,而test.ts文件则用于任何需要测试的场合,没有特定的用途或目标。

compose函数

const add1 = (x) => x + 1;
const mul3 = (x) => x * 3;
const div2 = (x) => x / 2;

function compose(...funcs){
    return function anonymous(val){debugger;
        if(funcs.length===0) return val;
        if(funcs.length===1) return funcs[0](val);
        return funcs.reverse().reduce((N,item)=>{
              return item(N)
        },val)
    }
}

compose(add1,mul3,div2)(3)

三、测试案例:

1、纯函数

export function sum(a:number, b:number):number {
  return a + b
}

2、composable函数

定义一个组合函数:

// composable 函数
import { ref, onMounted, onUnmounted } from 'vue'

// 按照惯例,组合式函数名以“use”开头
export function useMouse() {
  // 被组合式函数封装和管理的状态
  const x = ref(0)
  const y = ref(0)

  // 组合式函数可以随时更改其状态。
  function update(event) {
    x.value = event.pageX
    y.value = event.pageY
  }

  // 一个组合式函数也可以挂靠在所属组件的生命周期上
  // 来启动和卸载副作用
  onMounted(() => window.addEventListener('mousemove', update))
  onUnmounted(() => window.removeEventListener('mousemove', update))

  // 通过返回值暴露所管理的状态
  return { x, y }
}

 测试组合函数返回的值:

import { expect, test } from 'vitest'
import { useMouse } from '../../assets/mouse' // src\components\HelloWorld.vue
test('composable函数', () => {
  const { x, y } = useMouse();
  expect(x).toBeTruthy()
  expect(y).toBeTruthy()
})

3、store

piano代码:

// src/stores/index.ts
import { defineStore } from 'pinia'
interface UserType{
  userName:string
}

interface LoginObj{
  userName: string
  password:string
}
const getUser = (obj:LoginObj) => {
  return new Promise((res, rej) => {
    const { userName, password } = obj;
    setTimeout(() => {
      if (userName === '王五' && password === '123') {
        res({userName:'王五'})
      } else {
        rej(new Error('密码错误'))
      }
    },1000)
  })
}

export const useUserStore = defineStore('counter', {
  state: ():UserType => {
    return {
      userName:'未登录',
    }
  },
  getters: {
    doubleCount: (state) => state.userName,
  },
  actions: {
    async registerUser(userName:string, password:string) {
      try {
        const userData = await getUser({ userName, password });
        if (userData.userName) {
          this.userName = userData.userName;
        } else {
          console.log(userData)
        }
      } catch (error) {
       
        return error
      }
    },
  },
})

对 store 进行单元测试​

要对一个 store 进行单元测试,最重要的是创建一个 pinia 实例:

// tests/counter.spec.ts
import { setActivePinia, createPinia } from 'pinia'
import { useUserStore } from '../../stores'
import { describe, expect,test,beforeEach } from 'vitest'

describe('Counter Store', () => {
  beforeEach(() => {
    // 创建一个新 pinia,并使其处于激活状态,这样它就会被任何 useStore() 调用自动接收
    // 而不需要手动传递:
    // `useStore(pinia)`
    setActivePinia(createPinia())
  })

  test('increments', async () => {
    const counter = useUserStore()
    await expect(counter.userName).toBe('未登录')
    await counter.registerUser('王五','123')
    await expect(counter.userName).toBe('王五')
  })
    test('increments by amount', async () => {
      const counter = useUserStore()
      await expect(counter.userName).toBe('未登录')
      await counter.registerUser('王五', '1234')
      await expect(counter.userName).toBe('未登录')
    })
})

4、网络请求

<script setup lang="ts">
import { ref } from 'vue'
import MockAdapter from 'axios-mock-adapter'
import axios from 'axios'

const name = ref('李四')
const mock = new MockAdapter(axios)
const resulst = { name: '张三', age: 18 }

mock.onGet('/user').reply(200, resulst)
const handleRequestChange = () => {
  // 模拟接口
  axios.get('/user').then(res => {
    name.value = res.data.name
  })
}
</script>

<template>
  <span>{{ name }}</span>
  <button @click="handleRequestChange">get</button>
</template>

测试案例:文章来源地址https://www.toymoban.com/news/detail-812018.html

// api.spec.ts
import { vi, describe, it, expect } from 'vitest';
import { mount, flushPromises } from '@vue/test-utils'
import axios from 'axios';
import Axios from '../Axios.vue'

// console.log(0,Axios)

describe('axios-tets', () => {
  it('tets1', async () => {
    const spy = vi.spyOn(axios, 'get') //vi.mock 可以使用 vi.spyOn()监听 axios 的 get 请求来跟踪 mock 执行
    const wrapper = mount(Axios)
    await wrapper.find('button').trigger('click')
    expect(spy).toHaveBeenCalledTimes(1)
    expect(spy).toHaveBeenCalledWith('/user')
  })
  it('test2', async () => {
    const wrapper = mount(Axios)
    expect(wrapper.find('span').text()).toContain('李四')
    await wrapper.find('button').trigger('click')
    await flushPromises() // flushPromises方法会刷新所有已解决的 promise 程序
    expect(wrapper.find('span').text()).toContain('张三')
  })
})

5、延时函数

到了这里,关于Vitest 单元测试的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Vue3+Typescript+Vitest单元测试环境+基础用例篇

    近来工作接触了一个有意思的东西,那就是Vue3的单元测试。虽说写起来费时费力,但是它确实可以让我们设计的组件更加健壮、更加合理且风险可控,同时编写单元测试也让我们更近一步理解组件的设计原理,好了废话不多说,直接开始吧。 初始化一个vue3+typescript项目,移

    2024年02月10日
    浏览(46)
  • vitest 单元测试配合@vue/test-utils 之 axios 篇

    vitest 是由 vite 提供支持的极速单元测试框架,VueTestUtils 是 Vue.js 的官方测试实用程序库,Axios 是一个基于 promise 的网络请求库,以上均为各自官网对其的描述 项目中使用 axios 是非常常见的,所以我们可以对他做一个单元测试,在 test-utils 的文档中提到除了 jest.mock()还可以使

    2024年02月19日
    浏览(40)
  • 【vitest 单元测试】如何蹭 ant-design-web3 的PR

    这篇文章分享单测经验,希望你能收获到有用的单测知识或者pr思路,填补单测的过程可以深刻理解组件内部的每一个流程,相信一定有所收获。 最近刚好在做一些单测覆盖的工作,在排查执行不到的地方的过程,可以梳理整个组件执行的脉络,甚至发现一些可以优化组件的

    2024年01月16日
    浏览(37)
  • vite + vue3 的项目中使用 vitest 做单元测试(仅供参考)

    在 vitest 中 集成了c8,c8 是测试覆盖率检查的工具,告诉开发者代码中有哪些代码行被覆盖了,哪些没有覆盖。 在package.json增加npm script 如果没安装c8,运行命令的话,Vitest 会提示安装 c8,默认yes,回车执行安装。安装后,命令行删除测试覆盖率,同时在 src/coverage 下生成一个

    2024年02月03日
    浏览(49)
  • vitest第一章(初始vitest)

    从三个角度分析 vitest 他能做什么? 为什么要使用他? 使用它的优势是什么? vitest官网cn.vitest.dev/ 1.vitest能做什么 从官网介绍说这是一个 单元测试框架 ,大家听到有测试两个字觉得这个是测试同学写的东西,其实这个东西是帮助我们开发去测试代码。 例如我们在平时开发

    2023年04月19日
    浏览(34)
  • 【单元测试】--编写单元测试

    一、编写第一个单元测试 编写第一个单元测试通常包括以下步骤。以下示例以C#和NUnit为例: 创建测试项目 : 在Visual Studio中,创建一个新的Class Library项目,这将是你的单元测试项目。 在解决方案资源管理器中,右键点击项目,选择 “管理 NuGet 包”,然后搜索并安装NUnit框

    2024年02月07日
    浏览(44)
  • 单元测试:优雅编写Kotlin单元测试

    一、MockK简介 MockK是一款功能强大、易于使用的Kotlin mocking框架。在编写 单元测试 时,MockK能够帮助我们简化代码、提高测试覆盖率,并改善测试的可维护性。除了基本用法外,MockK还提供了许多额外的功能和灵活的用法,让我们能够更好地模拟对象行为、验证函数调用,并在

    2024年02月10日
    浏览(46)
  • 【单元测试】一文读懂java单元测试

    单元测试 是软件开发中常用的一种测试方法,用于验证代码的单个功能单元是否按照预期工作。 测试方法: 白盒测试(White Box Testing):在白盒测试中,测试人员了解代码的内部结构和实现细节,编写测试用例来覆盖不同的代码路径和逻辑条件。 黑盒测试(Black Box Testing)

    2024年04月17日
    浏览(45)
  • QTest 单元测试框架及单元测试思考

    在不同的公司和不同的项目上,常常会听到单元测试,但是真正能落实的确实寥寥无几,无非是在单元测试的开发时间和回报上模棱两可。 到底是否需要单元测试吗? 引用知乎观点如下: 第一个问题应该是,这个公司需要(覆盖率比较高的)测试么? 对于大部分公司来说,

    2023年04月08日
    浏览(80)
  • 单元测试之 - Review一个微服务的单元测试

    这里以github上一个microservice的demo代码为例,来看看如何为一个完整的服务编写单元测试。具体代码如下所示,我们重点查看一下catalog和customer,order中的单元测试有哪些。 首先来看catalog服务的单元测试,这个服务下面主要编写了CatalogWebIntegrationTest.java和RepositoryTest.java。下图是

    2024年02月14日
    浏览(43)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包