[go: up one dir, main page]

100% found this document useful (1 vote)
20K views29 pages

Getting To Know Jest

The document provides an overview of Jest, a JavaScript testing framework maintained by Facebook. It discusses how to get started with Jest, common matchers for testing values, using setup and teardown functions, mocking functions, and testing asynchronous code and React apps. Examples are given throughout for writing tests with Jest and using its various features.

Uploaded by

Mahesh VP
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
100% found this document useful (1 vote)
20K views29 pages

Getting To Know Jest

The document provides an overview of Jest, a JavaScript testing framework maintained by Facebook. It discusses how to get started with Jest, common matchers for testing values, using setup and teardown functions, mocking functions, and testing asynchronous code and React apps. Examples are given throughout for writing tests with Jest and using its various features.

Uploaded by

Mahesh VP
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
You are on page 1/ 29

Getting to Know Jest

In this course, you will learn:

 Introduction to Jest

 Getting Started with Jest

 Matchers in Jest

 Setup and Teardown

 Mock Functions

 Testing Asynchronous Code

 Testing React Apps

Delightful JavaScript Testing


Writing tests have high impact in application development. The application will
be stable and easy to maintain if the test results have few bugs.

Jest is a JavaScript unit testing framework, maintained by Facebook that lets you define
your unit tests.

Features of Jest
Mocking

 Jest Allows to mock objects in test files.


 Can mock specific objects or turn on automatic mocking with automock, which will
mock every object.
Snapshot Testing

 UI testing to become simplified as Jest can capture snapshots of React trees or other


serializable values.

Jest is Fast!
 Runs tests parallelly in processes to minimize test runtime.
 Runs previously failed tests first.
 Automatically finds tests related to changed files.
 Easy to set up JavaScript testing solution.
 Provides Test isolation i.e. no two tests will ever conflict with each other.
 Jest works well with other testing libraries (example Enzyme, Chai).

Who All Are Using Jest?

Jest is used by Leading companies to test web applications, node.js services, mobile


apps, and APIs.

Installing Jest

Install Jest using npm:


npm install jest

Or via yarn:

yarn add jest

Katacoda - A Playground for Jest

Katacoda is an interactive technical learning platform for software developers.

Here you can use Katacoda Node.js v6 Playground to practice Jesting (Javascript Testing)


by installing Jest in Katacoda Terminal.

First Test Using Jest

Create a sum.js file with a function that adds two numbers:

function sum(a, b) {

return a + b;}

module.exports = sum;

Create sum.test.js file. Let us get started by writing a test for the above function:

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

test('addition: 1+2=3', () =>{

expect(sum(1,2)).toBe(3);

});
Note: To create files, run the command touch <<filename>> in Katacoda terminal.

Run the Test


You can run Jest from the terminal and finally, you get test results.

Run all tests (default):

jest

Run only the tests that were stipulated with a pattern or filename:

jest sum.test --config=package.json

Voila!!! You just triumphantly wrote your first test using Jest!

Quick Fact

Jest runs all the files


with .spec.js and .test.jsextension in the current
directory.
Testing a To-do List Application

A simple To-do List Application has a lot of features to help you keep track of your daily
commitments - Anywhere. Anytime.

Let us test the javascript To-do List Application that has the following functions:

 addTask

 updateTask

 closeTask

 deleteTask

Testing a To-do List Application...


All hands-on across this course is based To-do list application , to explore your
understanding of the concepts and writing tests.

You can refer the To-do List JavaScript functions in Codepen and can make use of that when
you try to write tests on your own.

Introduction to Matchers

Jest utilizes matchers to test values in different ways. There are several matchers available


and this section will introduce few of the most useful ones like,

 Common Matchers

 Truthiness

 Numbers

 Strings

 Arrays

 Exceptions etc.

Common Matchers
Jest uses toBe and toEqual matchers to test a value is with exact equality.

 toBe which uses === to test exact equality.

```sh

test('2 + 2 = 4', () => {

expect(2 + 2).toBe(4);

});

```

 toEqual which recursively checks every field of an object or array.

```sh
test('obj assignment', () => {

const data = {one: 1};

data['two'] = 2;

expect(data).toEqual({one: 1, two: 2});

});

```

 Can also test for opposite of a matcher using not.toBe.

Truthiness
Sometimes you need to differentiate undefined, null, and false, but in some case, no need
to treat these differently.

Here are the helpers that let you be explicit about what you want.

 toBeNull matches only null
 toBeUndefined matches only undefined
 toBeDefined: opposite of toBeUndefined
 toBeTruthy matches anything that an if statement treats as true
 toBeFalsy matches anything that an if statement treats as false

Example for Truthiness


The following test program will explain the concept of truthiness in Jest.

test('zero', () => {

const z = 0;

expect(z).not.toBeNull();
expect(z).toBeDefined();

expect(z).not.toBeUndefined();

expect(z).not.toBeTruthy();

expect(z).toBeFalsy();

});

Matchers for Numbers


The number can be compared
using toBeGreaterThan, toBeGreaterThanOrEqual, toBeLessThan and toBeLessThanOrEqual.

The toBe and toEqual are equivalent for numbers.

test('1 + 1', () => {

const value = 1 + 1;

expect(value).toBeGreaterThan(3);

});

Here the test fails, because the sum is not greater than 3.

Matcher for Floating Point Numbers


To check equality of the floating point numbers, use toBeCloseTo instead of toEqual. This will
avoid the tiny rounding error that occurs while using toEqual.

test('Checking "toBe"', () => {

const value = 0.1 + 0.2;


expect(value).toBe(0.3);//rounding error

expect(value).toBeCloseTo(0.3); //works.

});

String Matcher
You can check strings against regular expressions with toMatch.

test('There is no "I" in Fresco Play', () => {

expect('Fresco Play').not.toMatch(/I/);

});

Array Matcher
Jest allows you to check if an array contains a particular item using toContain:

var employee=[];

employee=['Johns', 'Liani'];

test('Expects "Johns" in employee Array', () => {

expect(employee).toContain('Johns');

});

Exceptions
Use toThrow, if you want to test that a particular function throws an error when it is called.

Here is a sample test that shows four different ways of checking if a function throws an Error.
var employee= [];

function EmptyCheck() {

if( employee.length === 0){throw new Error('Empty Array');}

test('Empty check', () => {

expect(EmptyCheck).toThrow();

expect(EmptyCheck).toThrow(Error);

expect(EmptyCheck).toThrow('Empty Array');

expect(EmptyCheck).toThrow(/Empty/); //uses regexp

});

Setup and Teardown

Sometimes while writing tests, you have some setup work that has to happen before tests
run, and you have some finishing work that needs to happen after test run. Jest provides
some helper functions to handle this. Some of them are,

 beforeEach and  afterEach

 beforeAll and  afterAll

 describe

Repeating Setup For Many Tests


If you have some work that needs to do be done frequently for many tests, you can
use beforeEach and afterEach functions.

An Example for Repeating Setup


Consider you have Login tests that interact with the Employee DB.

Here we have two Login tests, where getData() is called before each test,


and clearData()is called after each test.

beforeEach(()=>{

getData();

});

afterEach(()=>{

clearData();

});

test('John: Logins',()=>{

expect(Login('John','**pswd**')).toBeTruthy();

});

test('Liani: Logins',()=>{

expect((Login('Liani','**pswd**')).toBeTruthy();

});

One-Time Setup
In some cases, you only need to do setup once, toward the start of a file. This can be
particularly annoying when the setup is asynchronous, so you cannot just do it inline. Jest
provides beforeAll and afterAll to deal with this circumstance.

One-Time Setup: Example


Consider you write tests for getDetails() and getExperience() which interacts with the
Employee DB.

If both initializeDB and releaseDB returned promises, and the Employee DB could be


reused between tests, we can write our test code as:

beforeAll(()=>{

return initializeDB();

});

afterAll(()=>{

return releaseDB();

});

test('Employee DB has John',()=>{

expect(checkEmployee('John')).toBeTruthy();

});

test('Checks experience of Liani',()=>{

expect(getExperience('Liani')).toBeGreaterThan('2');

});

Scoping
You can group tests together using a describe block. When they are inside a describe block,
the before and after blocks only apply to the tests within that describe block.

Scoping: An Example
For example, let us say we had not just a Cloud database, but also a Local database. We
could do a different setup for different tests:

// Applies to all tests in this file

beforeAll(() => {

return initializeCloudDB();

});

test('get updates from Cloud', () => {

expect(isConnected('CloudDB')).toBeTruthy();

});

describe('Connecting to local', () => {

// Applies only to tests in this describe block

beforeEach(() => {

return initializeLocalDB();

});

test('Updating local with cloud', () => {

expect(UpdateLocalDB('LocalDB','CloudDB')).toBe(true);

});

});
General Advice
If a test fails, the first thing that you have to check is whether the test is failing when it is the
only test that runs.

In Jest, it is simple to run only one test - just temporarily change that test command to
atest.only:

test.only('only test that runs', () => {

expect(true).toBe(false);

});

Introduction to Mock Functions


Mock Functions are simulated functions that mimic the behavior of the real ones by
isolating functionality into small, testable units under test.
Why Mock Functions?

 The real function is complex to incorporate it in a unit testing (Example, your


function has many networking calls)
 The result of your function is non-deterministic.

Different Ways to Mock Functions in Jest


You can create a mock function with jest.fn(). If no implementation is given, the mock
function will return undefined when invoked.

There are two ways to mock functions in Jest.

 By creating a mock function to use in test code


 By writing a manual mock to override a module dependency.

Trying a Mock Function


Let us take a simple example that myFun is mocked mockedFun in test.

function myFun(){
return "myFun called";

test('First Mock Function', () => {

mockedFun = jest.genMockFn();

mockedFun.mockImplementation(function () {

return "mockedFun called";

});

console.log(mockedFun());

});

Test Result will show the mockedFun called message.

.mock property
All mock functions have the special property called .mock, the place where all information
about how the function that has been called is kept.

These mock members are very useful in tests to assert how these functions get called, or
instantiated:

test('.mock property example', () => {

const mockFn = jest.fn();

const a = new mockFn();

console.log(mockFn.mock.instances.length); // is 1
});

Available Mock Methods


There are many functions related to mock in Jest. Let us check few of them.

 mock.calls
 mock.instances
 mockClear()
 mockReset()
 mockRestore()
 mockImplementation(fn) and mockImplementationOnce(fn)
 mockReturnValue(val) and mockReturnValueOnce(val)

mock.calls array
 Jest records all calls that have been made during mock function.
 Each call is represented by an array of arguments that were passed during the call.

For example, a mock function f is called twice, with the arguments f(arg1, arg2), and then
with the arguments f(arg3, arg4) would have a mock.calls array like below:

[ [arg1,arg2],
[arg3,arg4], ];

mock.instances array
 An array that records all the object instances that have been instantiated from the
mock function using new.

Below example has a mock function that has been instantiated twice.

test('.mock property example',()=>{

const mockFn = jest.fn();

const a = new mockFn();

const b = new mockFn();


console.log(mockFn.mock.instances[0] === a);//true

console.log(mockFn.mock.instances[1] === a);//false

});

mockClear() and mockReset()


mockClear()

 Resets all information stored in


the mockFn.mock.calls and mockFn.mock.instancesarrays.
 Useful when you have to clean up a mock's usage data between two assertions.
mockReset()
 Resets all information stored in the mock, also any inital implementation given.
 Useful when you want to completely restore a mock back to its initial state.

mockRestore()
 Will Remove the mock and restores the initial implementation.

 Helpful when you have to mock functions in particular test cases and restore the
original implementation in others.

 Only works when mock was created with jest.spyOn. Thus you have to take care of
restoration yourself when manually assigning jest.fn().

Mock Function Implementation


Function's actual implementations can be mocked in test using,

 mockImplementation(fn) - it allows to change the implementation for testing.


 mockImplementationOnce(fn) - it allows changing the implementation only once in the
entire testing process.

Mock Function Implementation Example


This Example explains the usage of mockImplementation and mockImplementationOnce.
function real(){

return "real";

test('Mock Implementation', () => {

mocked = jest.genMockFn();

mocked.mockImplementation(function () {

return "mocked";

});

mocked.mockImplementationOnce(function () {

return "mocked_once";

});

console.log(real()); //real

console.log(mocked()); //mocked_once

console.log(mocked(),mocked()); //mocked mocked

});

Mock Return Values


Mock functions can be used to inject test values into your code during a test using following
functions,
 mockReturnValue(value) returns the value when mock function is called.
 mockReturnValueOnce(value) returns the value only once when mock function is
called.

Mock Return Values Example


This Example explains the usage of mockReturnValueOnce and mockReturnValue.

test('Mock Returns',()=>{

const myMock = jest.fn();

myMock.mockReturnValueOnce("only once : mocked return ")

.mockReturnValue('mocked return');

console.log(myMock()); //only once : mocked return

console.log(myMock()); //mocked return

console.log(myMock()); //mocked return

});

Synchronous and Asynchronous Code


 The Synchronous Code will wait for first to finish before moving on to another task.

 But, when you execute an Asynchronous Code, it will move on to another task before it
finishes.

Testing Asynchronous Code Using Jest


As you test your Asynchronous code, Jest needs to know when the code testing has been
completed, before it can move on to different test.

Common asynchronous patterns are,

 Callbacks
 Promises etc.

What is Callback Function?


Callback is a function that is passed to another function as a parameter, and
the callback function is called inside the function.

Consider a function fetchData(Callback), which fetches status information and


calls callback(status), when it is complete.

function fetchData(callback) {

setTimeout(function () {

callback({status: 'completed'});

}, 2000);

Callbacks: Handling Asynchronous Tests


Instead of placing the test in a function with an empty argument, employ a single argument
called done.

Jest will wait until the done callback is called before finishing the test.

test('fetch data returns status completed', done => {

function callback(data) {

expect(data.status).toBe('completed');

done();

fetchData(callback);
});

Above test checks the status of fetchData function. You can also change the status in order
to understand the concept better.

Promises: Handling Asynchronous Tests


If your code uses promises, just return a promise, and Jest will wait for that promise to
resolve. The test will fail automatically if the promise is rejected.

Consider the following functions which return promises.

function first() {

var promise = new Promise(function(resolve, reject){

setTimeout(function() {

console.log('first');

resolve('first');}, 2000);

});

return promise;

function second() {

var promise = new Promise(function(resolve, reject){

setTimeout(function() {
console.log('second');

resolve('second');}, 2000);

});

return promise;

};

.resolves: Handling Asynchronous Tests


You can also use the .resolves matcher in your expect statement, and Jest will wait for that
promise to resolve. If the promise is rejected, the test will automatically fail.

test('Promise to be resolved', () => {

expect(first()

.then(second)

.resolves.toBe('second');

});

.rejects: Handling Asynchronous Tests


If you expect a promise to be rejected use the .rejects matcher. If the promise is fulfilled, the
test will automatically fail.

function second() {

var promise = new Promise(function(resolve, reject){

setTimeout(function() {
console.log('second');

reject('error in second');}, 2000);

});

return promise;

};

test('Promise to be rejected', () => {

expect(first()

.then(second)

.rejects.toBe('error');

});

Testing React Apps


React is a declarative, efficient, and flexible  JavaScript library for building user
interfaces.

If you are just getting started with React, we recommend you to go through the
course ReactJS first.

Creating a New React App


React Application is the best way to start building single page application.

Here we can create a simple app called my-app using following commands.

npm install -g create-react-app


create-react-app my-app

cd my-app

npm start

Hello World Application


The easiest way to get started with React is to use this Hello World example code.

//index.html

<div id="root">

<!-- This element's contents will be replaced with your component. -->

</div>

//index.js

ReactDOM.render(

<h1>Hello, world!</h1>,

document.getElementById('root')

);

Jest Setup for React Apps


Run the following command to install Jest.

$ npm install jest


 In the app folder, create a folder, __tests__ to store the test files.
 To run the added test use the below command.

```sh

npm run test //or npm test or npm t

Quick Fact

By default, Jest searches all directories for the test folder


with name __test__ and runs all .js files inside it.
Testing React Components with Enzyme
To assert and manipulate rendered components, you can use Enzyme or React's TestUtils.
Here we use Enzyme for this example.

Enzyme is a JavaScript Testing utility for React that makes it easier to assert, manipulate,
and traverse a React Component's output.

 To install Enzyme, run the following command:

```sh

$ npm install --save-dev enzyme react-addons-test-utils

```

Why Enzyme?
Front end code behaviors in your UI should also be tested as well in React applications.

Here is an example which shows how Enzyme tests React components.

//welcome.jsx

export default class Welcome extends React.Component {


render() {

return (

<div>Hello world</div>

);

Why Enzyme?
The test for the Welcome component using Enzyme is shown below.

import React from 'react';

import expect from 'expect';

import { shallow } from 'enzyme';

import Welcome from '../src/client/components/welcome.jsx';

describe('Welcome', () => {

it('Welcome renders hello world', () => {

const welcome = shallow(<Welcome />);

expect(welcome.find('div').text()).toEqual('Hello world');

});
});

Introduction to Snapshot Testing

Snapshot tests are a useful tool whenever you want to make sure your UI does not change
unexpectedly.

It is a way to test your UI component without writing actual test cases.

How Snapshot Testing works?


Here is how it works:

 Step 1: Save a snapshot of a single state of UI.


 Step 2: While adding a new feature, it generates new snapshots for the updated UI
components.
 Step 3: Then it compares it to a reference image stored alongside the test.

The word snapshot has nothing to do with images or screenshots. They are purely textual.

What is Code Coverage?


Code coverage tests that how much code is covered under tests.

In contrast to a program with low code coverage, a program with high code coverage in %,
has a lower chance of featuring undetected software bugs.

Code Coverage in Jest


Jest has built-in code coverage reporter that creates code coverage reports easily using
the command,

jest --coverage

 No additional setup or libraries required!


 Can gather code coverage information from the entire projects, which includes
untested files.

Why Code Coverage?


Here we have functions add() and sub() in calc.js and have calc.test.js for the same.

calc.js

function add(a, b) { return a + b; }

function sub(a, b) { return a - b; }

module.exports = { add: add, sub: sub};

calc.test.js

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

test('add:1+2=3',()=>{

expect(add(1,2)).toBe(3);

});

Why Code Coverage?...


The previous unit test will pass, even if you have not tested the function sub().

But the code coverage gives a test coverage of 50% and ensures that your tests are testing
your code or not.

You can use coverage reports to identify critical misses in our unit tests.

Code Coverage in Continuous Integration


Consider a large application, where multiple developers are working
together, maintaining the code quality and fixing bugs; which is a very tedious task.

In this scenario, the Code Coverage is the ideal approach to motivate the developers to write
more unit tests to avoid the chances of getting errors after integration.
Code Coverage in Continuous Integration...
Ideally, the CI pipeline should have a code coverage target of 100%, that is the entire
application code is covered by unit tests.

The build can be set to fail if the coverage did not match the required threshold.

Course Summary
In this course you have read:

 Introduction to Jest
 Getting Started with Jest
 Matchers in Jest
 Setup and Teardown
 Mock Functions
 Testing Asynchronous Code
 Testing React Apps

If you want to get in deep with Jest, the better to place to start is Jest-Delightful JavaScript
Testing.

Quiz
1. Jest is maintained by ______________ . FACEBOOK
2. Jest works well with other testing libraries like ______________. ALL
3. Jest is used to test _____________. JAVASCRIPT
4. How to install Jest using npm? NPM INSTALL--SAVE-DEV TEST
5. Jest is a JavaScript unit testing framework. T
6. The number can be compared using __________. ALL
7. ______________ matcher matches only undefined. TO BE UNDEFINED
8. Jest uses ________ and ________ matchers to test a value is with exact equality. TO BE, TO
EQUAL
9. The below test will pass.
10. Jest records all calls that have been made during mock function and it is stored
in ______________ array. MOCK.CALLS
11. ______________ resets all information stored in the mockFn.mock.calls and mockFn.mock.instances
arrays. MOCK CLEAR
12. .mock is a property of mock function, the place where all information about how the function has been
called is kept. T
13. Jest supports ______________ for Isolating functionality into small, testable units under test. MOCK
FUNCTIONS
14. Jest will wait until the ______________ callback is called before finishing the test. DONE
15. When you execute ______________ Code, it will move on to another task before it finishes.
ASYNCHRONOUS
16. Snapshot tests are a useful tool whenever you want to make sure your UI does not change
unexpectedly. T
17. The Asynchronous code will move on to another task before it finishes. T
18. Code coverage tests that how much code is covered under tests. T
19. mockRestore() works only when mock was created with ______________. jest.spyOn
20. ______________ is an array that records all the object instances that have been instantiated from the
mock function using new. MOCK.INSTANCES
21. mockRestore() removes the mock and restores the initial implementation. T
22. What is the command to install Jest and the babel-jest ? npm install --save-dev jest
23. Snapshot Testing is not supported in Jest. F
24. How to run your test in terminal? NPM-RUN TEST
25. const value = 0.1 + 0.2; F
26. expect(value).toBe(0.3);
27. The matcher toContain is used _________. ARRAY
28. ______________ is useful when you want to completely restore a mock back to its initial state.
mockReset()
29. To test a particular function which throws an error when it's called, you can usetoThrow.T
30. .mock is a property of mock function, the place where all information about how the function has been
called is kept. T
31. Jest is used by ______________. All of these
32. For Code Coverage Support Jest requires some additional setup and libraries . F
33. ______________ resets all information stored in the mock, including any inital implementation given.
MOCK RESTORE
34. ______________ returns the value only once when mock function is called.
MOCKRETURNVALUEONCE(VALUE)
35. Which method is useful to clean up a mock's usage data between two assertions. MOCK CLEAR
36. If you expect a promise to be rejected, use the ______________ matcher. If the promise is fulfilled, the
test will automatically fail. REJECT
37. ______________ recursively checks every field of an object or array. TO EQUAL
38. The Synchronous Code will move on to another task before it finishes. F
39. How to install Jest using yarn? YARN ADD--DEV JEST
40. ______________ matcher matches only undefined. toBeUndefined
41. To create a mock function, we use jest.fn(). T
42. ______________ recursively checks every field of an object or array. toEqual
43. ______________ is useful when you want to mock functions in certain test cases and restore the
original implementation in others. mockRestore()
44. mockRestore() removes the mock and restores the initial implementation T

You might also like