What is Jest?
It is a javascript testing framework, which is easy to use and understand. It works with node, react, angular, babel and much more. Easy to set up and use, along with precise error messages which help to write error-free tests.
The naming of these test files is given as follows name.test.js
, add the following script in your package.json and now we can run the test by using npm run test
command.
{
"scripts": {
"test": "jest"
}
}
Suppose we have functions defined in a file.
function sum(a, b) {
return a + b;
}
module.exports = sum;
Now we will see how can we test them. First of all, we will import them into our test file.
const sum = require('./sum');
test('adds 1 + 2 to equal 3', () => {
expect(sum(1, 2)).toBe(3);
});
Terminologies -
describe block - It helps group related tests together under a common heading, making it easier to understand and manage tests.
describe('Family Photos', () => { test('Photo of mom', () => { // This is a specific test (photo) for your mom. }); test('Photo of dad', () => { // This is a specific test (photo) for your dad. }); });
test block - a way to group a specific piece of testing logic.
test('description of what this test does', () => { // The actual testing logic goes here });
expect -
expect(something).matcher(value);
something
is the actual value or result produced by your code.matcher
is a method that tells Jest how to comparesomething
with the expectedvalue
.
expect(2 + 2).toBe(4);
Basics of jest -
The primary block you use to define a test in Jest is the test
function, though it
is also frequently used as an alias. Inside these blocks, you write your assertions using the expect
function combined with various matches.
Matchers -
// truthiness test('null', () => { const n = null; expect(n).toBeNull(); expect(n).toBeDefined(); expect(n).not.toBeUndefined(); expect(n).not.toBeTruthy(); expect(n).toBeFalsy(); }); // numbers test('numbers', () => { const valu = 5 + 5; 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(10); expect(value).toEqual(10); }); // strings using regex test('there is no I in team', () => { expect('team').not.toMatch(/I/); }); // arrays const arr = [1,2,3]; test("check",()=>{ expect(arr).toContain(2); }) //exceptions function throwError() { throw new Error("error thrown") } test("running",()=>{ expect(()=>throwError()).toThrow(); })
Testing async code -
// promises - let's say fetchD is a promise which fetches data test("test promise",()=>{ return fetchD().then(d=>{ expect(d).toBe("data") }) }) // async/await - let's say fetchD is a async function now test('test async', async () => { const data = await fetchD(); expect(data).toBe("data"); }); // callbacks - done keyword Jest will wait until // the done callback is called before finishing the test. test('the data is peanut butter', done => { function callback(error, data) { if (error) { done(error); return; } try { expect(data).toBe('peanut butter'); done(); } catch (error) { done(error); } } fetchData(callback); }); // resolves/reject test('resolve and reject', () => { return expect(fetchD()).resolves.toBe('data'); });
Setup and teardown -
// repeating things need to execute for test rather executing it // again and again we will put it inside a block // will run before each test beforeEach(() => { initializeCityDatabase(); }); // will run after each test afterEach(() => { clearCityDatabase(); }); // one time setup // will run before all tests execute beforeAll(() => { return initializeCityDatabase(); }); // will run after all tests has been executed afterAll(() => { return clearCityDatabase(); });
The top level
before*
andafter*
hooks apply to every test in a file. The hooks declared inside adescribe
block apply only to the tests within thatdescribe
block. This is what is known as scoping.Talking about the order of execution, jest first executes describe block before actually running any of the tests inside it. Once the
describe
blocks are complete, by default Jest runs all the tests serially in the order they were encountered.
Mock functions - In code testing, sometimes we have parts of our code (often called "dependencies") that aren't the main focus of our test or might cause complications if used directly (like making actual network requests, interacting with a database, etc.). Instead of using the real thing, we use a "mock function" as a stand-in. This mock function will mimic the behavior of the real function but in a controlled manner.
You will understand it better from the docs itself.
In case you need an easier example and explanation for specific things in jest you can comment below for the same.