├── .gitignore ├── 04_mock ├── mock.js └── mock.test.js ├── 02_sync ├── sync.js └── sync.spec.js ├── 01_intro ├── intro.js └── intro.test.js ├── package.json └── 03_async ├── async.js └── async.spec.js /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | .idea 3 | -------------------------------------------------------------------------------- /04_mock/mock.js: -------------------------------------------------------------------------------- 1 | function map(array, callback) { 2 | const result = [] 3 | for (let i = 0; i < array.length; i++) { 4 | result.push(callback(array[i])) 5 | } 6 | return result 7 | } 8 | 9 | module.exports = {map} 10 | -------------------------------------------------------------------------------- /02_sync/sync.js: -------------------------------------------------------------------------------- 1 | class Lodash { 2 | compact(array) { 3 | return array.filter(val => !!val) 4 | } 5 | 6 | groupBy(array, prop) { 7 | return array.reduce((acc, i) => { 8 | const key = typeof prop === 'function' ? prop(i) : i[prop] 9 | if (!acc[key]) { 10 | acc[key] = [] 11 | } 12 | acc[key].push(i) 13 | return acc 14 | }, {}) 15 | } 16 | } 17 | 18 | module.exports = Lodash 19 | -------------------------------------------------------------------------------- /01_intro/intro.js: -------------------------------------------------------------------------------- 1 | function expect(value) { 2 | return { 3 | toBe: exp => { 4 | if (value === exp) { 5 | console.log('Success') 6 | } else { 7 | console.error(`Value is ${value}, but expectation is ${exp}`) 8 | } 9 | } 10 | } 11 | } 12 | 13 | const sum = (a, b) => a + b 14 | 15 | const nativeNull = () => null 16 | 17 | module.exports = {sum, nativeNull} 18 | 19 | // expect(sum(41, 1)).toBe(43) 20 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "intro-unit-testing", 3 | "version": "1.0.0", 4 | "description": "Jest intro", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "jest" 8 | }, 9 | "keywords": [ 10 | "js", 11 | "javascript", 12 | "jest", 13 | "unti", 14 | "testing" 15 | ], 16 | "author": "Vladilen ", 17 | "license": "ISC", 18 | "devDependencies": { 19 | "jest": "^24.9.0" 20 | }, 21 | "dependencies": { 22 | "axios": "^0.19.1" 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /03_async/async.js: -------------------------------------------------------------------------------- 1 | const axios = require('axios') 2 | 3 | class Ajax { 4 | static echo(data) { 5 | return new Promise((resolve, reject) => { 6 | setTimeout(() => { 7 | if (data) { 8 | resolve(data) 9 | } else { 10 | reject(new Error('error')) 11 | } 12 | }, 150) 13 | }) 14 | } 15 | 16 | static async get() { 17 | try { 18 | const response = await axios.get('https://jsonplaceholder.typicode.com/todos') 19 | return response.data 20 | } catch (e) { 21 | console.log(e) 22 | } 23 | } 24 | } 25 | 26 | module.exports = Ajax 27 | -------------------------------------------------------------------------------- /04_mock/mock.test.js: -------------------------------------------------------------------------------- 1 | const {map} = require('./mock') 2 | 3 | describe('Map function', () => { 4 | let array 5 | let fn 6 | 7 | beforeEach(() => { 8 | array = [1, 2, 3, 5] 9 | fn = jest.fn(x => x ** 2) 10 | map(array, fn) 11 | }) 12 | 13 | 14 | test('should call callback', () => { 15 | expect(fn).toBeCalled() 16 | }) 17 | 18 | test('should call callback 4 times', () => { 19 | expect(fn).toBeCalledTimes(4) 20 | expect(fn.mock.calls.length).toBe(4) 21 | }) 22 | 23 | test('should pow 2 each element', () => { 24 | expect(fn.mock.results[0].value).toBe(1) 25 | expect(fn.mock.results[1].value).toBe(4) 26 | expect(fn.mock.results[2].value).toBe(9) 27 | expect(fn.mock.results[3].value).toBe(25) 28 | }) 29 | 30 | test('should fn work', () => { 31 | fn 32 | .mockReturnValueOnce(100) 33 | .mockReturnValueOnce(200) 34 | .mockReturnValue('42') 35 | 36 | expect(fn()).toBe(100) 37 | expect(fn()).toEqual(200) 38 | expect(fn()).toEqual('42') 39 | expect(fn()).toEqual('42') 40 | }) 41 | }) 42 | -------------------------------------------------------------------------------- /01_intro/intro.test.js: -------------------------------------------------------------------------------- 1 | const {sum, nativeNull} = require('./intro') 2 | 3 | describe('Sum function:', () => { 4 | test('should return sum of two values', () => { 5 | expect(sum(1, 3)).toBe(4) 6 | expect(sum(1, 3)).toEqual(4) 7 | }) 8 | 9 | test('should return value correctly comparing to other values', () => { 10 | expect(sum(2, 3)).toBeGreaterThan(4) 11 | expect(sum(2, 3)).toBeGreaterThanOrEqual(5) 12 | expect(sum(2, 3)).toBeLessThan(10) 13 | expect(sum(2, 3)).toBeLessThanOrEqual(5) 14 | }) 15 | 16 | test('should sum 2 float values correctly', () => { 17 | expect(sum(0.1, 0.2)).toBeCloseTo(0.3) 18 | }) 19 | }) 20 | 21 | describe('Native null function:', () => { 22 | 23 | test('should return false value null', () => { 24 | expect(nativeNull()).toBe(null) 25 | expect(nativeNull()).toBeNull() 26 | expect(nativeNull()).toBeFalsy() // undefined, null, 0, '' 27 | expect(nativeNull()).toBeDefined() 28 | expect(nativeNull()).not.toBeTruthy() 29 | expect(nativeNull()).not.toBeUndefined() 30 | }) 31 | 32 | }) 33 | 34 | 35 | 36 | -------------------------------------------------------------------------------- /03_async/async.spec.js: -------------------------------------------------------------------------------- 1 | const axios = require('axios') 2 | const Ajax = require('./async') 3 | 4 | jest.mock('axios') 5 | 6 | describe('Ajax: echo', () => { 7 | 8 | test('should return value async', async () => { 9 | const result = await Ajax.echo('some data') 10 | expect(result).toBe('some data') 11 | }) 12 | 13 | test('should return value with promise', () => { 14 | return Ajax.echo('some data').then(data => { 15 | expect(data).toBe('some data') 16 | }) 17 | }) 18 | 19 | test('should catch error with promise', () => { 20 | return Ajax.echo().catch(err => { 21 | expect(err).toBeInstanceOf(Error) 22 | }) 23 | }) 24 | 25 | test('should catch error with promise', async () => { 26 | try { 27 | await Ajax.echo() 28 | } catch (e) { 29 | expect(e.message).toBe('error') 30 | } 31 | }) 32 | 33 | }) 34 | 35 | 36 | describe('Ajax: GET', () => { 37 | let response 38 | let todos 39 | 40 | beforeEach(() => { 41 | todos = [ 42 | {id: 1, title: 'Todo 1', completed: false} 43 | ] 44 | 45 | response = { 46 | data: { 47 | todos 48 | } 49 | } 50 | }) 51 | 52 | test('should return data from backend', () => { 53 | axios.get.mockReturnValue(response) 54 | 55 | return Ajax.get().then(data => { 56 | expect(data.todos).toEqual(todos) 57 | }) 58 | }) 59 | 60 | }) 61 | -------------------------------------------------------------------------------- /02_sync/sync.spec.js: -------------------------------------------------------------------------------- 1 | const Lodash = require('./sync') 2 | 3 | let _ = new Lodash() 4 | 5 | describe('Lodash: compact', () => { 6 | let array = [false, 42, 0, '', true, null, 'hello'] 7 | 8 | beforeEach(() => { 9 | array = [false, 42, 0, '', true, null, 'hello'] 10 | }) 11 | 12 | afterAll(() => { 13 | _ = new Lodash() 14 | }) 15 | 16 | test('should be defined', () => { 17 | expect(_.compact).toBeDefined() 18 | expect(_.compact).not.toBeUndefined() 19 | }) 20 | 21 | test('should working array be editable', () => { 22 | array.push(...['one', 'two']) 23 | expect(array).toContain('one') 24 | expect(array).toContain('two') 25 | }) 26 | 27 | test('should remove falsy values from array', () => { 28 | const result = [42, true, 'hello'] 29 | expect(_.compact(array)).toEqual(result) 30 | }) 31 | 32 | test('should NOT contain falsy values', () => { 33 | expect(_.compact(array)).not.toContain(false) 34 | expect(_.compact(array)).not.toContain(0) 35 | expect(_.compact(array)).not.toContain('') 36 | expect(_.compact(array)).not.toContain(null) 37 | }) 38 | 39 | }) 40 | 41 | 42 | describe('Lodash: groupBy', () => { 43 | test('should be defined', () => { 44 | expect(_.groupBy).toBeDefined() 45 | expect(_.groupBy).not.toBeUndefined() 46 | }) 47 | 48 | test('should group array items by Math.floor', () => { 49 | const array = [2.2, 2.4, 4.2, 3.1] 50 | const result = { 51 | 2: [2.2, 2.4], 52 | 4: [4.2], 53 | 3: [3.1] 54 | } 55 | expect(_.groupBy(array, Math.floor)).toEqual(result) 56 | }) 57 | 58 | test('should group array items by length', () => { 59 | const array = ['one', 'two', 'three'] 60 | const result = { 61 | 5: ['three'], 62 | 3: ['one', 'two'] 63 | } 64 | expect(_.groupBy(array, 'length')).toEqual(result) 65 | }) 66 | 67 | test('should NOT return array', () => { 68 | expect(_.groupBy([], Math.trunc)).not.toBeInstanceOf(Array) 69 | }) 70 | }) 71 | --------------------------------------------------------------------------------