jest (people testing framework pleasant)

jest (people testing framework pleasant)

1 What is Jest

Jest JavaScript testing framework is a set of open-source Facebook, it automatically integrates assertion, all the test tools JSDom, coverage reports and other developers need, it is a testing framework almost zero configuration.

2 Installation

Use yarn to install Jest

yarn add --dev jest
复制代码

Or npm:

npm install --save-dev jest
复制代码

3 simple trial

First, let's write a first summing function sum.js

function sum(a, b){
    return a + b;
}
module.exports = sum;
复制代码

Next, create a test case:

const sum = require('./sum');

test('adds 1 + 2 to equal 3', () => {
    expect(sum(1, 2)).toBe(3);
})
复制代码

Configuring test startup scripts in package.json in:

{
    "scripts": {
        "test": "jest"
    }
}
复制代码

Finally, run the yarn test or npm run test, Jest will print the following message:

PASS ./sum.test.js
✓ adds 1 + 2 to equal 3 (5ms)
复制代码

4 matcher

Ordinary matcher

The simplest test is to compare whether an exact match

test(`two plus tow is four`, () => {
    expect(2 + 2).toBe(4);
})
复制代码

Truthiness

In the test, sometimes it requires precision to distinguish between undefined, null and false, and sometimes they do not need to distinguish between, jest are met.

  • toBeNull only match null
  • toBeUndefined match only undefined
  • Instead toBeDefined and toBeUndefined
  • toBeTruthy match any if statement is true
  • toBeFalsy match any if statement is false
test('null', () => {
  const n = null;
  expect(n).toBeNull();
  expect(n).toBeDefined();
  expect(n).not.toBeUndefined();
  expect(n).not.toBeTruthy();
  expect(n).toBeFalsy();
});

test('zero', () => {
  const z = 0;
  expect(z).not.toBeNull();
  expect(z).toBeDefined();
  expect(z).not.toBeUndefined();
  expect(z).not.toBeTruthy();
  expect(z).toBeFalsy();
});
复制代码

digital

Most of the comparative figures have equivalent matcher.

test('two plus two', () => {
  const value = 2 + 2;
  expect(value).toBeGreaterThan(3);
  expect(value).toBeGreaterThanOrEqual(3.5);
  expect(value).toBeLessThan(5);
  expect(value).toBeLessThanOrEqual(4.5);

  // toBe and toEqual are equivalent for numbers
  expect(value).toBe(4);
  expect(value).toEqual(4);
});
复制代码

For comparison float equal, instead of using toBeCloseTo toEqual, because you do not want to test depends on a small rounding error.

test('两个浮点数字相加', () => {
  const value = 0.1 + 0.2;
  //expect(value).toBe(0.3);           这句会报错,因为浮点数有舍入误差
  expect(value).toBeCloseTo(0.3); // 这句可以运行
});
复制代码

String

toMatch regular expression string ︰

test('there is no I in team', () => {
  expect('team').not.toMatch(/I/);
});

test('but there is a "stop" in Christoph', () => {
  expect('Christoph').toMatch(/stop/);
});
复制代码

Arrays and iterables

You can check whether an array or iteration object contains a specific item by toContain:

const shoppingList = [
  'diapers',
  'kleenex',
  'trash bags',
  'paper towels',
  'beer',
];

test('the shopping list has beer on it', () => {
  expect(shoppingList).toContain('beer');
  expect(new Set(shoppingList)).toContain('beer');
});
复制代码

exception

Specific function tests throw an error when it is called with toThrow.

function compileAndroidCode() {
  throw new ConfigError('you are using the wrong JDK');
}

test('compiling android goes as expected', () => {
  expect(compileAndroidCode).toThrow();
  expect(compileAndroidCode).toThrow(ConfigError);

  // You can also use the exact error message or a regexp
  expect(compileAndroidCode).toThrow('you are using the wrong JDK');
  expect(compileAndroidCode).toThrow(/JDK/);
});
复制代码

5 test asynchronous code

Callback

test('the data is peanut butter', done => {
  function callback(data) {
    expect(data).toBe('peanut butter');
    done();
  }

  fetchData(callback);
});
复制代码

Promises

test('the data is peanut butter', () => {
  return fetchData().then(data => {
    expect(data).toBe('peanut butter');
  });
});
复制代码

.resloves/.rejects

test('the data is peanut butter', () => {
  return expect(fetchData()).resolves.toBe('peanut butter');
});
复制代码
test('the fetch fails with an error', () => {
  return expect(fetchData()).rejects.toMatch('error');
});
复制代码

Async/Await

test('the data is peanut butter', async () => {
  const data = await fetchData();
  expect(data).toBe('peanut butter');
});

test('the fetch fails with an error', async () => {
  expect.assertions(1);
  try {
    await fetchData();
  } catch (e) {
    expect(e).toMatch('error');
  }
});
复制代码

6 Mount and unloading (Setup and Teardown)

For the writing test of time before you need to do some preparatory work to run the test, and some of the finishing work after running the test.

The test was repeated several times to set

beforeEach(() => {
  initializeCityDatabase();
});

afterEach(() => {
  clearCityDatabase();
});

test('city database has Vienna', () => {
  expect(isCity('Vienna')).toBeTruthy();
});

test('city database has San Juan', () => {
  expect(isCity('San Juan')).toBeTruthy();
});
复制代码

One-time setup

beforeAll(() => {
  return initializeCityDatabase();
});

afterAll(() => {
  return clearCityDatabase();
});

test('city database has Vienna', () => {
  expect(isCity('Vienna')).toBeTruthy();
});

test('city database has San Juan', () => {
  expect(isCity('San Juan')).toBeTruthy();
});
复制代码

Scope

By default, before and after the blocks can be applied to the file for each test. Further may describe the test packets through the block. When describe the before and after the block inside the block, it applies only to describe tests within the block.

// Applies to all tests in this file
beforeEach(() => {
  return initializeCityDatabase();
});

test('city database has Vienna', () => {
  expect(isCity('Vienna')).toBeTruthy();
});

test('city database has San Juan', () => {
  expect(isCity('San Juan')).toBeTruthy();
});

describe('matching cities to foods', () => {
  // Applies only to tests in this describe block
  beforeEach(() => {
    return initializeFoodDatabase();
  });

  test('Vienna <3 sausage', () => {
    expect(isValidCityFoodPair('Vienna', 'Wiener Schnitzel')).toBe(true);
  });

  test('San Juan <3 plantains', () => {
    expect(isValidCityFoodPair('San Juan', 'Mofongo')).toBe(true);
  });
});

复制代码

6 function test (mockFunction)

Using mock function

function forEach(items, callback) {
  for (let index = 0; index < items.length; index++) {
    callback(items[index]);
  }
}

const mockCallback = jest.fn(x => 42 + x);
forEach([0, 1], mockCallback);

// The mock function is called twice
expect(mockCallback.mock.calls.length).toBe(2);

// The first argument of the first call to the function was 0
expect(mockCallback.mock.calls[0][0]).toBe(0);

// The first argument of the second call to the function was 1
expect(mockCallback.mock.calls[1][0]).toBe(1);

// The return value of the first call to the function was 42
expect(mockCallback.mock.results[0].value).toBe(42);
复制代码

mock the return value

const myMock = jest.fn();
console.log(myMock());
// > undefined

myMock
  .mockReturnValueOnce(10)
  .mockReturnValueOnce('x')
  .mockReturnValue(true);

console.log(myMock(), myMock(), myMock(), myMock());
// > 10, 'x', true, true
复制代码

7 snapshots (snapshot)

After assembly using the snapshot function to make a snapshot, and the snapshot easily adjust the contrast back

React use of test renderer and Jest snapshot characteristics and component interaction, rendering the results and get a snapshot of the file:

import React from 'react';
import Link from '../Link.react';
import renderer from 'react-test-renderer';

test('Link changes the class when hovered', () => {
  const component = renderer.create(
    <Link page="http://www.facebook.com">Facebook</Link>,
  );
  let tree = component.toJSON();
  expect(tree).toMatchSnapshot();

  // manually trigger the callback
  tree.props.onMouseEnter();
  // re-rendering
  tree = component.toJSON();
  expect(tree).toMatchSnapshot();

  // manually trigger the callback
  tree.props.onMouseLeave();
  // re-rendering
  tree = component.toJSON();
  expect(tree).toMatchSnapshot();
});
复制代码

Reproduced in: https: //juejin.im/post/5d072e136fb9a07ecd3d5c73

Guess you like

Origin blog.csdn.net/weixin_33733810/article/details/93174172