Jest, Javascript unit testing
Unit Testing in JavaScript
Overview
Use Jest for unit and integration tests and TestCafe for UI tests.
- Jest is a testing framework by Facebook.
- Set up is easy
- Jest finds your tests automatically
- Jest runs in parallel
- Jest looks simple, like plain English
- Jest can be debugged just like any other Node.JS module
- Jest is watching
Set up
-
npm init -y
npm i -D jest
-d
will save it as dependency- in package.json, scripts, add
"test":"jest"
"testwatch":"jest --watchAll"
,npm run testwatch
Write a simple unit test
- Add a file function.js with following:
const functions = { add: (num1, num2)=> num1+num2 }; module.exports = functions;
- Add a test file: functions.test.js
const functions = require('./functions'); test('Adds 2 + 2 to equal 4', () => { expect(functions.add(2,3)).toBe(4); // will fail });
- run test:
npm test
will trigger jest
Write other unit tests
Not
- Declare it in test name
- use
not.toBe()
functions.test.jsconst functions = require('./functions'); test('Adds 2 + 2 to NOT equal 5', () => { expect(functions.add(2,2)).not.toBe(5); });
Asset null
const functions = {
add: (num1, num2)=> num1+num2,
isNull:()=> null
};
module.exports = functions;
const functions = require('./functions');
test('Should be null', () => {
expect(functions.isNull()).toBeNull();
});
Check value
toBeFalsy()
equals tonot.toBeTruesy()
toBeTruesy
const functions = {
add: (num1, num2)=> num1+num2,
isNull:()=> null,
checkValue:(x)=>x
};
module.exports = functions;
const functions = require('./functions');
test('Should be falsy', () => {
expect(functions.checkValue(null)).toBeFalsy(); // will pass
});
test('Should be falsy', () => {
expect(functions.checkValue(0)).toBeFalsy(); // will pass
});
test('Should be falsy', () => {
expect(functions.checkValue(undefined)).toBeFalsy(); // will pass
});
test('Should be falsy', () => {
expect(functions.checkValue(2)).toBeFalsy(); // will fail
});
Objects
toBe()
is for primitive type- should use
toEqual()
for object
const functions = {
add: (num1, num2)=> num1+num2,
isNull:()=> null,
checkValue:(x)=>x,
createUser:() => {
const user = {firstName: 'Moss';
user['lastName'] = 'Gu';
return user;
}
};
module.exports = functions;
test('User should be Moss Gu object', () => {
expect(functions.createUser(undefined))
.toEqual({firstName:'Moss',lastname:'Gu'}); // will do
expect(functions.createUser(undefined))
.toBe({firstName:'Moss',lastname:'Gu'}); // will pass
});
Less than and greater than
toBeLessThan()
toBeLessThanOrEqual()
test('Should be under 1600', ()=> {
const load1 = 800;
const load2 = 700;
expect(load1 + load2).toBeLessThan(1600); // will pass
});
test('Should be under 1600', ()=> {
const load1 = 800;
const load2 = 800;
expect(load1 + load2).toBeLessThan(1600); // will fail
expect(load1 + load2).toBeLessThanOrEqual(1600); // will pass
});
Regex
toMatch()
test('There is no I in team', ()=> { expect('team').not.toMatch(/I/); // will pass });
Array
toContain()
toMatch()
test('Admin should be in username', ()=> { usernames = ['moss','feifei','haha']; expect(users).toContain('admin'); //will fail expect(users).toContain('haha'); //will pass });
Async, Promise
- Install axios:
npm i axios
- For demo purpose, we use JSONP_PLACEHOLDER
const axios = require('axios');
const functions = {
fetchUser: () => axios.get('https://jsonplaceholder.typicode.com/users/1')
.then(res => res.data)
.catch(err => 'error)
};
module.exports = functions;
test('User fetched name should be Leanne Graham', () => {
expect.assetions(1);
return functions.fetchUser()
.then(data => {
expect(data.name).toEqual('Leanne Graham);
});
});
Async, Await
test('User fetched name should be Leanne Graham', () => {
expect.assetions(1);
const data = functions.fetchUser();
expect(data.name).toEqual('Leanne Graham);
});
Function
toBeDefined()
toEqual()
reversestring.js
const reverseString = str =>
str
.toUpperCase()
.split('')
.reverse()
.join('');
module.exports = reverseString;
reversestring.test.js
const reverseString = require('/reversestring');
test('reverseString function exists', () => {
expect(reverseString).toBeDefined();
});
test('String reverses', () => {
expect(reverseString('hello')).toEqual('Olleh');
});
test('String reverse with UPPERCASE', () => {
expect(reverseString('Hello')).toEqual('olleh');
});
Chunks
chunk.js
const chunkArray = (arr, len) => {
//int chunked arr
const chunkedArr = [];
//loop through arr
arr.forEach(val => {
//get last element
const last = chunkedArr[chunkedArr.length - 1];
//check if last and if last length is equal to the chunk len
if(!last || last.length === len){
chunkArr.push([val]);
} else {
last.push(value);
}
});
return chunkArr;
}
module.exports = chunkArray;
chunk.test.js
const chunkArray = require('./chunk);
test('chunkArray function exists', () => {
expect(chunkArray).toBeDefined();
});
test('Chunk an array of 10 values with length of 2', () => {
const numbers = [1,2,3,4,5,6,7,8,9,10];
const len = 2;
const chunkedArr = chunkArray(numbers, len);
expect(chunkedArr).toEqual([1,2],[3,4],[5,6],[7,8],[9,10]); //shall pass
});
Lifecycle thingees
- run fucntions before and after each test
const initDB = () => console.log('db initialized'); const closeDB = () => console.log('db closed'); beforeEach(() => initDB()); afterEach(() => close());
- run fucntions before all and after all tests
const initDB = () => console.log('db initialized'); const closeDB = () => console.log('db closed'); beforeAll(() => initDB()); afterAll(() => close());
- Run beforeEach inside of a functon
const nameCheck = () => console.log('checking names...'); describ('Checking names', () => { beforeEach(() => nameCheck()); test('user is jeff', () => { const user = 'jeff'; expect(user).toBe('Jeff'); }); test('user is moss', () => { const user = 'moss'; expect(user).toBe('moss'); }); });
Notes
This blog is my note from: Jest Crash Course - Unit Testing in JavaScript.