vue-jest测试用例_用Jest测试JavaScript

vue-jest测试用例

笑话简介 (Introduction to Jest)

Jest is a library for testing JavaScript code.

Jest是用于测试JavaScript代码的库。

It’s an open source project maintained by Facebook, and it’s especially well suited for React code testing, although not limited to that: it can test any JavaScript code. Its strengths are:

这是Facebook维护的一个开源项目,它特别适合于React代码测试,但不仅限于此:它可以测试任何JavaScript代码。 它的优势是:

  • it’s fast

    它很快
  • it can perform snapshot testing

    它可以执行快照测试

  • it’s opinionated, and provides everything out of the box without requiring you to make choices

    固执己见,并提供所有现成的内容,而无需您做出选择

Jest is a tool very similar to Mocha, although they have differences:

Jest是与Mocha非常相似的工具,尽管它们之间存在差异:

  • Mocha is less opinionated, while Jest has a certain set of conventions

    摩卡(Mocha)固执己见,而杰斯特(Jest)有一些约定
  • Mocha requires more configuration, while Jest works usually out of the box, thanks to being opinionated

    Mocha需要更多配置,而Jest通常开箱即用,这要归功于他们的自以为是
  • Mocha is older and more established, with more tooling integrations

    摩卡(Mocha)更老,更成熟,具有更多的工具集成

In my opinion the biggest feature of Jest is it’s an out of the box solution that works without having to interact with other testing libraries to perform its job.

在我看来,Jest的最大特点是它是一种即用型解决方案,无需与其他测试库进行交互即可执行其工作。

安装 (Installation)

Jest is automatically installed in create-react-app, so if you use that, you don’t need to install Jest.

Jest会自动安装在create-react-app ,因此,如果您使用它,则无需安装Jest。

Jest can be installed in any other project using Yarn:

Jest可以使用Yarn安装在任何其他项目中:

yarn add --dev jest

or npm:

npm

npm install --save-dev jest

notice how we instruct both to put Jest in the devDependencies part of the package.json file, so that it will only be installed in the development environment and not in production.

注意,我们如何指示两者将Jest放在package.json文件的devDependencies部分中,以便仅将其安装在开发环境中,而不能在生产环境中安装。

Add this line to the scripts part of your package.json file:

将此行添加到package.json文件的脚本部分:

{
  "scripts": {
    "test": "jest"
  }
}

so that tests can be run using yarn test or npm run test.

这样可以使用yarn testnpm run test

Alternatively, you can install Jest globally:

或者,您可以全局安装Jest:

yarn global add jest

and run all your tests using the jest command line tool.

并使用jest命令行工具运行所有测试。

创建第一个Jest测试 (Create the first Jest test)

Projects created with create-react-app have Jest installed and preconfigured out of the box, but adding Jest to any project is as easy as typing

使用create-react-app项目已经安装并预先配置了Jest,但是将Jest添加到任何项目就像键入一样容易

yarn add --dev jest

Add to your package.json this line:

package.json下行添加到package.json

{
  "scripts": {
    "test": "jest"
  }
}

and run your tests by executing yarn test in your shell.

并通过在外壳中执行yarn test来运行测试。

Now, you don’t have any tests here, so nothing is going to be executed:

现在,您在这里没有任何测试,因此将不执行任何操作:

Testing with Yarn

Let’s create the first test. Open a math.js file and type a couple functions that we’ll later test:

让我们创建第一个测试。 打开math.js文件,并输入几个函数,稍后我们将对其进行测试:

const sum = (a, b) => a + b
const mul = (a, b) => a * b
const sub = (a, b) => a - b
const div = (a, b) => a / b

module.exports = { sum, mul, sub, div }

Now create a math.test.js file, in the same folder, and there we’ll use Jest to test the functions defined in math.js:

现在,在同一文件夹中创建一个math.test.js文件,在这里我们将使用Jest测试math.js定义的功能:

const { sum, mul, sub, div } = require('./math')

test('Adding 1 + 1 equals 2', () => {
  expect(sum(1, 1)).toBe(2)
})
test('Multiplying 1 * 1 equals 1', () => {
  expect(mul(1, 1)).toBe(1)
})
test('Subtracting 1 - 1 equals 0', () => {
  expect(sub(1, 1)).toBe(0)
})
test('Dividing 1 / 1 equals 1', () => {
  expect(div(1, 1)).toBe(1)
})

Running yarn test results in Jest being run on all the test files it finds, and returning us the end result:

在Jest上运行的yarn test结果将在它发现的所有测试文件上运行,并向我们返回最终结果:

Passing tests

用VS Code运行Jest (Run Jest with VS Code)

Visual Studio Code is a great editor for JavaScript development. The Jest extension offers a top notch integration for our tests.

Visual Studio Code是JavaScript开发的出色编辑器。 Jest扩展为我们的测试提供了一流的集成。

Once you install it, it will automatically detect if you have installed Jest in your devDependencies and run the tests. You can also invoke the tests manually by selecting the Jest: Start Runner command. It will run the tests and stay in watch mode to re-run them whenever you change one of the files that have a test (or a test file):

安装后,它将自动检测是否已在devDependencies中安装了Jest并运行测试。 您也可以通过选择Jest:Start Runner命令来手动调用测试。 每当您更改具有测试的文件之一(或测试文件)时,它将运行测试并停留在监视模式下以重新运行它们:

A simple Jest test running in VS Code

匹配器 (Matchers)

In the previous article I used toBe() as the only matcher:

在上一篇文章中,我使用toBe()作为唯一的匹配器

test('Adding 1 + 1 equals 2', () => {
  expect(sum(1, 1)).toBe(2)
})

A matcher is a method that lets you test values.

匹配器是一种允许您测试值的方法。

Most commonly used matchers, comparing the value of the result of expect() with the value passed in as argument, are:

最常用的匹配器,将Expect expect()结果的值与作为参数传递的值进行比较,它们是:

  • toBe compares strict equality, using ===

    toBe使用===比较严格相等

  • toEqual compares the values of two variables. If it’s an object or array, it checks the equality of all the properties or elements

    toEqual比较两个变量的值。 如果是对象或数组,则检查所有属性或元素的相等性

  • toBeNull is true when passing a null value

    传递null值时, toBeNull为true

  • toBeDefined is true when passing a defined value (opposite to the above)

    传递定义的值时, toBeDefined为true(与上述相反)

  • toBeUndefined is true when passing an undefined value

    传递未定义的值时, toBeUndefined为true

  • toBeCloseTo is used to compare floating values, avoiding rounding errors

    toBeCloseTo用于比较浮动值,避免舍入错误

  • toBeTruthy true if the value is considered true (like an if does)

    toBeTruthy如果该值被视为true,则为true(如if那样)

  • toBeFalsy true if the value is considered false (like an if does)

    toBeFalsy如果该值被视为false,则为true(如if那样)

  • toBeGreaterThan true if the result of expect() is higher than the argument

    如果toBeGreaterThan ()的结果高于参数, toBeGreaterThan true

  • toBeGreaterThanOrEqual true if the result of expect() is equal to the argument, or higher than the argument

    toBeGreaterThanOrEqual如果toBeGreaterThanOrEqual ()的结果等于参数,或者高于参数, toBeGreaterThanOrEqual true

  • toBeLessThan true if the result of expect() is lower than the argument

    如果toBeLessThan ()的结果低于参数, toBeLessThan true

  • toBeLessThanOrEqual true if the result of expect() is equal to the argument, or lower than the argument

    toBeLessThanOrEqual如果toBeLessThanOrEqual ()的结果等于参数,或者小于参数, toBeLessThanOrEqual true

  • toMatch is used to compare strings with regular expression pattern matching

    toMatch用于比较具有正则表达式模式匹配的字符串

  • toContain is used in arrays, true if the expected array contains the argument in its elements set

    toContain用于数组中,如果期望的数组在其元素集中包含参数,则为true

  • toHaveLength(number): checks the length of an array

    toHaveLength(number) :检查数组的长度

  • toHaveProperty(key, value): checks if an object has a property, and optionally checks its value

    toHaveProperty(key, value) :检查对象是否具有属性,并可选地检查其值

  • toThrow checks if a function you pass throws an exception (in general) or a specific exception

    toThrow检查您传递的函数是否抛出异常(通常)或特定异常

  • toBeInstanceOf(): checks if an object is an instance of a class

    toBeInstanceOf() :检查对象是否是类的实例

All those matchers can be negated using .not. inside the statement, for example:

可以使用.not.否定所有这些匹配器.not. 在语句中,例如:

test('Adding 1 + 1 does not equal 3', () => {
  expect(sum(1, 1)).not.toBe(3)
})

For use with promises, you can use .resolves and .rejects:

与promise一起使用时,可以使用.resolves.rejects

expect(Promise.resolve('lemon')).resolves.toBe('lemon')

expect(Promise.reject(new Error('octopus'))).rejects.toThrow('octopus')

建立 (Setup)

Before running your tests you will want to perform some initialization.

在运行测试之前,您将需要执行一些初始化。

To do something once before all the tests run, use the beforeAll() function:

要在所有测试运行之前执行一次操作,请使用beforeAll()函数:

beforeAll(() => {
  //do something
})

To perform something before each test runs, use beforeEach():

要在每次测试运行之前执行某些操作,请使用beforeEach()

beforeEach(() => {
  //do something
})

拆除 (Teardown)

Just as you can do with setup, you can also perform something after each test runs:

就像您可以进行设置一样,您还可以在每次测试运行后执行一些操作:

afterEach(() => {
  //do something
})

and after all tests end:

在所有测试结束后:

afterAll(() => {
  //do something
})

使用describe()进行组测试 (Group tests using describe())

You can create groups of tests, in a single file, that isolate the setup and teardown functions:

您可以在单个文件中创建测试组,以隔离设置和拆卸功能:

describe('first set', () => {
  beforeEach(() => {
    //do something
  })
  afterAll(() => {
    //do something
  })
  test(/*...*/)
  test(/*...*/)
})

describe('second set', () => {
  beforeEach(() => {
    //do something
  })
  beforeAll(() => {
    //do something
  })
  test(/*...*/)
  test(/*...*/)
})

测试异步代码 (Testing asynchronous code)

Asynchronous code in modern JavaScript can have basically 2 forms: callbacks and promises. On top of promises we can use async/await.

现代JavaScript中的异步代码基本上可以有两种形式:回调和承诺。 除了承诺,我们还可以使用async / await。

回呼 (Callbacks)

You can’t have a test in a callback, because Jest won’t execute it - the execution of the test file ends before the callback is called. To fix this, pass a parameter to the test function, which you can conveniently call done. Jest will wait until you call done() before ending that test:

您不能在回调中进行测试,因为Jest不会执行测试-测试文件的执行在调用回调之前结束。 要解决此问题,请将参数传递给测试函数,您可以方便地调用done 。 Jest将等到您调用完done()之后再结束该测试:

//uppercase.js
function uppercase(str, callback) {
  callback(str.toUpperCase())
}
module.exports = uppercase

//uppercase.test.js
const uppercase = require('./src/uppercase')

test(`uppercase 'test' to equal 'TEST'`, (done) => {
  uppercase('test', (str) => {
    expect(str).toBe('TEST')
    done()
  }
})

Jest async test callback

承诺 (Promises)

With functions that return promises, we return a promise from the test:

使用返回承诺的函数,我们从测试中返回承诺

//uppercase.js
const uppercase = str => {
  return new Promise((resolve, reject) => {
    if (!str) {
      reject('Empty string')
      return
    }
    resolve(str.toUpperCase())
  })
}
module.exports = uppercase

//uppercase.test.js
const uppercase = require('./uppercase')
test(`uppercase 'test' to equal 'TEST'`, () => {
  return uppercase('test').then(str => {
    expect(str).toBe('TEST')
  })
})

Jest async test promises

Promises that are rejected can be tested using .catch():

可以使用.catch()测试被拒绝的承诺:

//uppercase.js
const uppercase = str => {
  return new Promise((resolve, reject) => {
    if (!str) {
      reject('Empty string')
      return
    }
    resolve(str.toUpperCase())
  })
}

module.exports = uppercase

//uppercase.test.js
const uppercase = require('./uppercase')

test(`uppercase 'test' to equal 'TEST'`, () => {
  return uppercase('').catch(e => {
    expect(e).toMatch('Empty string')
  })
})

Jest async test catch

异步/等待 (Async/await)

To test functions that return promises we can also use async/await, which makes the syntax very straightforward and simple:

为了测试返回promise的函数,我们还可以使用async / await,这使得语法非常简单明了:

//uppercase.test.js
const uppercase = require('./uppercase')
test(`uppercase 'test' to equal 'TEST'`, async () => {
  const str = await uppercase('test')
  expect(str).toBe('TEST')
})

Jest async test await async

模拟 (Mocking)

In testing, mocking allows you to test functionality that depends on:

在测试中, 模拟使您可以测试依赖于以下功能的功能:

  • Database

    数据库

  • Network requests

    网络请求

  • access to Files

    访问文件

  • any External system

    任何外部系统

so that:

以便:

  1. your tests run faster, giving a quick turnaround time during development

    您的测试运行速度更快 ,从而在开发过程中缩短了周转时间

  2. your tests are independent of network conditions, or the state of the database

    您的测试与网络条件或数据库状态无关

  3. your tests do not pollute any data storage because they do not touch the database

    您的测试不会污染任何数据存储,因为它们不会影响数据库

  4. any change done in a test does not change the state for subsequent tests, and re-running the test suite should start from a known and reproducible starting point

    测试中所做的任何更改都不会更改后续测试的状态,并且重新运行测试套件应从已知且可复制的起点开始
  5. you don’t have to worry about rate limiting on API calls and network requests

    您不必担心API调用和网络请求的速率限制

Mocking is useful when you want to avoid side effects (e.g. writing to a database) or you want to skip slow portions of code (like network access), and also avoids implications with running your tests multiple times (e.g. imagine a function that sends an email or calls a rate-limited API).

当您想要避免副作用(例如,写入数据库)或希望跳过代码的慢速部分(例如,网络访问),并且还可以避免多次运行测试(例如,假设某个函数发送一个电子邮件或调用受速率限制的API)。

Even more important, if you are writing a Unit Test, you should test the functionality of a function in isolation, not with all its baggage of things it touches.

更重要的是,如果您正在编写单元测试 ,则应该隔离测试功能的功能,而不是对其涉及的所有事物进行测试。

Using mocks, you can inspect if a module function has been called and which parameters were used, with:

使用模拟,您可以通过以下方法检查是否已调用模块函数以及使用了哪些参数:

  • expect().toHaveBeenCalled(): check if a spied function has been called

    expect().toHaveBeenCalled() :检查是否已调用间谍函数

  • expect().toHaveBeenCalledTimes(): count how many times a spied function has been called

    expect().toHaveBeenCalledTimes() :计算一个间谍函数被调用了多少次

  • expect().toHaveBeenCalledWith(): check if the function has been called with a specific set of parameters

    expect().toHaveBeenCalledWith() :检查是否已使用一组特定的参数调用了该函数

  • expect().toHaveBeenLastCalledWith(): check the parameters of the last time the function has been invoked

    expect().toHaveBeenLastCalledWith() :检查上次调用该函数的参数

间谍软件包而不会影响功能代码 (Spy packages without affecting the functions code)

When you import a package, you can tell Jest to “spy” on the execution of a particular function, using spyOn(), without affecting how that method works.

导入包时,可以使用spyOn()告诉Jest对特定功能的执行进行“间谍”,而不会影响该方法的工作方式。

Example:

例:

const mathjs = require('mathjs')

test(`The mathjs log function`, () => {
  const spy = jest.spyOn(mathjs, 'log')
  const result = mathjs.log(10000, 10)

  expect(mathjs.log).toHaveBeenCalled()
  expect(mathjs.log).toHaveBeenCalledWith(10000, 10)
})

模拟整个包裹 (Mock an entire package)

Jest provides a convenient way to mock an entire package. Create a __mocks__ folder in the project root, and in this folder create one JavaScript file for each of your packages.

Jest提供了模拟整个程序包的便捷方法。 在项目根目录中创建一个__mocks__文件夹,并在此文件夹中为每个包创建一个JavaScript文件。

Say you import mathjs. Create a __mocks__/mathjs.js file in your project root, and add this content:

假设您导入mathjs 。 在项目根目录中创建__mocks__/mathjs.js文件,并添加以下内容:

module.exports = {
  log: jest.fn(() => 'test')
}

This will mock the log() function of the package. Add as many functions as you want to mock:

这将模拟包的log()函数。 添加任意数量的要模拟的函数:

const mathjs = require('mathjs')

test(`The mathjs log function`, () => {
  const result = mathjs.log(10000, 10)
  expect(result).toBe('test')
  expect(mathjs.log).toHaveBeenCalled()
  expect(mathjs.log).toHaveBeenCalledWith(10000, 10)
})

模拟一个功能 (Mock a single function)

You can mock a single function using jest.fn():

您可以使用jest.fn()模拟单个函数:

const mathjs = require('mathjs')

mathjs.log = jest.fn(() => 'test')
test(`The mathjs log function`, () => {
  const result = mathjs.log(10000, 10)
  expect(result).toBe('test')
  expect(mathjs.log).toHaveBeenCalled()
  expect(mathjs.log).toHaveBeenCalledWith(10000, 10)
})

You can also use jest.fn().mockReturnValue('test') to create a simple mock that does nothing except returning a value.

您还可以使用jest.fn().mockReturnValue('test')创建一个简单的模拟程序,除了返回值外,该模拟程序不执行任何操作。

预先建立的模拟 (Pre-built mocks)

You can find pre-made mocks for popular libraries. For example this package https://github.com/jefflau/jest-fetch-mock allows you to mock fetch() calls, and provide sample return values without interacting with the actual server in your tests.

您可以找到流行库的预制模型。 例如,此程序包https://github.com/jefflau/jest-fetch-mock允许您模拟fetch()调用,并提供示例返回值,而无需与测试中的实际服务器进行交互。

快照测试 (Snapshot testing)

Snapshot testing is a pretty cool feature offered by Jest. It can memorize how your UI components are rendered, and compare it to the current test, raising an error if there’s a mismatch.

快照测试是Jest提供的一项很酷的功能。 它可以记住UI组件的呈现方式,并将其与当前测试进行比较,如果不匹配,则会引发错误。

This is a simple test on the App component of a simple create-react-app application (make sure you install react-test-renderer):

这是对一个简单的create-react-app应用程序的App组件的简单测试(确保安装了react-test-renderer ):

import React from 'react'
import App from './App'
import renderer from 'react-test-renderer'

it('renders correctly', () => {
  const tree = renderer.create(<App />).toJSON()
  expect(tree).toMatchSnapshot()
})

the first time you run this test, Jest saves the snapshot to the __snapshots__ folder. Here’s what App.test.js.snap contains:

第一次运行此测试时,Jest将快照保存到__snapshots__文件夹中。 这是App.test.js.snap包含的内容:

// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`renders correctly 1`] = `
<div
  className="App"
>
  <header
    className="App-header"
  >
    <img
      alt="logo"
      className="App-logo"
      src="logo.svg"
    />
    <h1
      className="App-title"
    >
      Welcome to React
    </h1>
  </header>
  <p
    className="App-intro"
  >
    To get started, edit
    <code>
      src/App.js
    </code>
     and save to reload.
  </p>
</div>
`

As you see it’s the code that the App component renders, nothing more.

如您所见,这是App组件呈现的代码,仅此而已。

The next time the test compares the output of <App /> to this. If App changes, you get an error:

下次测试将<App />的输出与此进行比较时。 如果应用程序发生更改,则会出现错误:

Error with snapshot

When using yarn test in create-react-app you are in watch mode, and from there you can press w and show more options:

create-react-app使用yarn test ,您处于观看模式 ,然后可以按w并显示更多选项:

Watch Usage
 › Press u to update failing snapshots.
 › Press p to filter by a filename regex pattern.
 › Press t to filter by a test name regex pattern.
 › Press q to quit watch mode.
 › Press Enter to trigger a test run.

If your change is intended, pressing u will update the failing snapshots, and make the test pass.

如果您打算进行更改,请按u将更新失败的快照,并通过测试。

You can also update the snapshot by running jest -u (or jest --updateSnapshot) outside of watch mode.

您还可以通过在监视模式之外运行jest -u (或jest --updateSnapshot )来更新快照。

翻译自: https://flaviocopes.com/jest/

vue-jest测试用例

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值