• United States+1
  • United Kingdom+44
  • Afghanistan (‫افغانستان‬‎)+93
  • Albania (Shqipëri)+355
  • Algeria (‫الجزائر‬‎)+213
  • American Samoa+1684
  • Andorra+376
  • Angola+244
  • Anguilla+1264
  • Antigua and Barbuda+1268
  • Argentina+54
  • Armenia (Հայաստան)+374
  • Aruba+297
  • Australia+61
  • Austria (Österreich)+43
  • Azerbaijan (Azərbaycan)+994
  • Bahamas+1242
  • Bahrain (‫البحرين‬‎)+973
  • Bangladesh (বাংলাদেশ)+880
  • Barbados+1246
  • Belarus (Беларусь)+375
  • Belgium (België)+32
  • Belize+501
  • Benin (Bénin)+229
  • Bermuda+1441
  • Bhutan (འབྲུག)+975
  • Bolivia+591
  • Bosnia and Herzegovina (Босна и Херцеговина)+387
  • Botswana+267
  • Brazil (Brasil)+55
  • British Indian Ocean Territory+246
  • British Virgin Islands+1284
  • Brunei+673
  • Bulgaria (България)+359
  • Burkina Faso+226
  • Burundi (Uburundi)+257
  • Cambodia (កម្ពុជា)+855
  • Cameroon (Cameroun)+237
  • Canada+1
  • Cape Verde (Kabu Verdi)+238
  • Caribbean Netherlands+599
  • Cayman Islands+1345
  • Central African Republic (République centrafricaine)+236
  • Chad (Tchad)+235
  • Chile+56
  • China (中国)+86
  • Christmas Island+61
  • Cocos (Keeling) Islands+61
  • Colombia+57
  • Comoros (‫جزر القمر‬‎)+269
  • Congo (DRC) (Jamhuri ya Kidemokrasia ya Kongo)+243
  • Congo (Republic) (Congo-Brazzaville)+242
  • Cook Islands+682
  • Costa Rica+506
  • Côte d’Ivoire+225
  • Croatia (Hrvatska)+385
  • Cuba+53
  • Curaçao+599
  • Cyprus (Κύπρος)+357
  • Czech Republic (Česká republika)+420
  • Denmark (Danmark)+45
  • Djibouti+253
  • Dominica+1767
  • Dominican Republic (República Dominicana)+1
  • Ecuador+593
  • Egypt (‫مصر‬‎)+20
  • El Salvador+503
  • Equatorial Guinea (Guinea Ecuatorial)+240
  • Eritrea+291
  • Estonia (Eesti)+372
  • Ethiopia+251
  • Falkland Islands (Islas Malvinas)+500
  • Faroe Islands (Føroyar)+298
  • Fiji+679
  • Finland (Suomi)+358
  • France+33
  • French Guiana (Guyane française)+594
  • French Polynesia (Polynésie française)+689
  • Gabon+241
  • Gambia+220
  • Georgia (საქართველო)+995
  • Germany (Deutschland)+49
  • Ghana (Gaana)+233
  • Gibraltar+350
  • Greece (Ελλάδα)+30
  • Greenland (Kalaallit Nunaat)+299
  • Grenada+1473
  • Guadeloupe+590
  • Guam+1671
  • Guatemala+502
  • Guernsey+44
  • Guinea (Guinée)+224
  • Guinea-Bissau (Guiné Bissau)+245
  • Guyana+592
  • Haiti+509
  • Honduras+504
  • Hong Kong (香港)+852
  • Hungary (Magyarország)+36
  • Iceland (Ísland)+354
  • India (भारत)+91
  • Indonesia+62
  • Iran (‫ایران‬‎)+98
  • Iraq (‫العراق‬‎)+964
  • Ireland+353
  • Isle of Man+44
  • Israel (‫ישראל‬‎)+972
  • Italy (Italia)+39
  • Jamaica+1876
  • Japan (日本)+81
  • Jersey+44
  • Jordan (‫الأردن‬‎)+962
  • Kazakhstan (Казахстан)+7
  • Kenya+254
  • Kiribati+686
  • Kosovo+383
  • Kuwait (‫الكويت‬‎)+965
  • Kyrgyzstan (Кыргызстан)+996
  • Laos (ລາວ)+856
  • Latvia (Latvija)+371
  • Lebanon (‫لبنان‬‎)+961
  • Lesotho+266
  • Liberia+231
  • Libya (‫ليبيا‬‎)+218
  • Liechtenstein+423
  • Lithuania (Lietuva)+370
  • Luxembourg+352
  • Macau (澳門)+853
  • Macedonia (FYROM) (Македонија)+389
  • Madagascar (Madagasikara)+261
  • Malawi+265
  • Malaysia+60
  • Maldives+960
  • Mali+223
  • Malta+356
  • Marshall Islands+692
  • Martinique+596
  • Mauritania (‫موريتانيا‬‎)+222
  • Mauritius (Moris)+230
  • Mayotte+262
  • Mexico (México)+52
  • Micronesia+691
  • Moldova (Republica Moldova)+373
  • Monaco+377
  • Mongolia (Монгол)+976
  • Montenegro (Crna Gora)+382
  • Montserrat+1664
  • Morocco (‫المغرب‬‎)+212
  • Mozambique (Moçambique)+258
  • Myanmar (Burma) (မြန်မာ)+95
  • Namibia (Namibië)+264
  • Nauru+674
  • Nepal (नेपाल)+977
  • Netherlands (Nederland)+31
  • New Caledonia (Nouvelle-Calédonie)+687
  • New Zealand+64
  • Nicaragua+505
  • Niger (Nijar)+227
  • Nigeria+234
  • Niue+683
  • Norfolk Island+672
  • North Korea (조선 민주주의 인민 공화국)+850
  • Northern Mariana Islands+1670
  • Norway (Norge)+47
  • Oman (‫عُمان‬‎)+968
  • Pakistan (‫پاکستان‬‎)+92
  • Palau+680
  • Palestine (‫فلسطين‬‎)+970
  • Panama (Panamá)+507
  • Papua New Guinea+675
  • Paraguay+595
  • Peru (Perú)+51
  • Philippines+63
  • Poland (Polska)+48
  • Portugal+351
  • Puerto Rico+1
  • Qatar (‫قطر‬‎)+974
  • Réunion (La Réunion)+262
  • Romania (România)+40
  • Russia (Россия)+7
  • Rwanda+250
  • Saint Barthélemy (Saint-Barthélemy)+590
  • Saint Helena+290
  • Saint Kitts and Nevis+1869
  • Saint Lucia+1758
  • Saint Martin (Saint-Martin (partie française))+590
  • Saint Pierre and Miquelon (Saint-Pierre-et-Miquelon)+508
  • Saint Vincent and the Grenadines+1784
  • Samoa+685
  • San Marino+378
  • São Tomé and Príncipe (São Tomé e Príncipe)+239
  • Saudi Arabia (‫المملكة العربية السعودية‬‎)+966
  • Senegal (Sénégal)+221
  • Serbia (Србија)+381
  • Seychelles+248
  • Sierra Leone+232
  • Singapore+65
  • Sint Maarten+1721
  • Slovakia (Slovensko)+421
  • Slovenia (Slovenija)+386
  • Solomon Islands+677
  • Somalia (Soomaaliya)+252
  • South Africa+27
  • South Korea (대한민국)+82
  • South Sudan (‫جنوب السودان‬‎)+211
  • Spain (España)+34
  • Sri Lanka (ශ්‍රී ලංකාව)+94
  • Sudan (‫السودان‬‎)+249
  • Suriname+597
  • Svalbard and Jan Mayen+47
  • Swaziland+268
  • Sweden (Sverige)+46
  • Switzerland (Schweiz)+41
  • Syria (‫سوريا‬‎)+963
  • Taiwan (台灣)+886
  • Tajikistan+992
  • Tanzania+255
  • Thailand (ไทย)+66
  • Timor-Leste+670
  • Togo+228
  • Tokelau+690
  • Tonga+676
  • Trinidad and Tobago+1868
  • Tunisia (‫تونس‬‎)+216
  • Turkey (Türkiye)+90
  • Turkmenistan+993
  • Turks and Caicos Islands+1649
  • Tuvalu+688
  • U.S. Virgin Islands+1340
  • Uganda+256
  • Ukraine (Україна)+380
  • United Arab Emirates (‫الإمارات العربية المتحدة‬‎)+971
  • United Kingdom+44
  • United States+1
  • Uruguay+598
  • Uzbekistan (Oʻzbekiston)+998
  • Vanuatu+678
  • Vatican City (Città del Vaticano)+39
  • Venezuela+58
  • Vietnam (Việt Nam)+84
  • Wallis and Futuna+681
  • Western Sahara (‫الصحراء الغربية‬‎)+212
  • Yemen (‫اليمن‬‎)+967
  • Zambia+260
  • Zimbabwe+263
  • Åland Islands+358
Thanks! We'll be in touch in the next 12 hours
Oops! Something went wrong while submitting the form.

Beginner’s Guide for Writing Unit Test Cases with Jest Framework

Siddharth Jain

Unit Testing/ Backend Development

Prerequisite

Basic JavaScript, TypeScript

Objective

To make the reader understand the use/effect of test cases in software development.

What’s in it for you?

In the world of coding, we're often in a rush to complete work before a deadline hits. And let's be honest, writing test cases isn't usually at the top of our priority list. We get it—they seem tedious, so we’d rather skip this extra step. But here's the thing: those seemingly boring lines of code have superhero potential. Don't believe me? You will.

In this blog, we're going to break down the mystery around test cases. No jargon, just simple talk. We'll chat about what they are, explore a handy tool called Jest, and uncover why these little lines are actually the unsung heroes of coding. So, let's ditch the complications and discover why giving some attention to test cases can level up our coding game. Ready? Let's dive in!

What are test cases?

A test case is a detailed document specifying conditions under which a developer assesses whether a software application aligns with customer requirements. It includes preconditions, the case name, input conditions, and expected results. Derived from test scenarios, test cases cover both positive and negative inputs, providing a roadmap for test execution. This one-time effort aids future regression testing.

Test cases offer insights into testing strategy, process, preconditions, and expected outputs. Executed during testing, they ensure the software performs its intended tasks. Linking defects to test case IDs facilitates efficient defect reporting. The comprehensive documentation acts as a safeguard, catching any oversights during test case execution and reinforcing the development team's efforts.

Different types of test cases exist, including integration, functional, non-functional, and unit.
For this blog, we will talk about unit test cases.

What are unit test cases?

Unit testing is the process of testing the smallest functional unit of code. A functional unit could be a class member or simply a function that does something to your input and provides an output. Test cases around those functional units are called unit test cases.

Purpose of unit test cases

  • To validate that each unit of the software works as intended and meets the requirements:
    For example, if your requirement is that the function returns an object with specific properties, a unit test will detect whether the code is written accordingly.
  • To check the robustness of code:
    Unit tests are automated and run each time the code is changed to ensure that new code does not break existing functionality.
  • To check the errors and bugs beforehand:
    If a case fails or doesn’t fulfill the requirement, it helps the developer isolate the area and recheck it for bugs before testing on demo/UAT/staging.

Different frameworks for writing unit test cases

There are various frameworks for unit test cases, including:

  • Mocha
  • Storybook
  • Cypress
  • Jasmine
  • Puppeteer
  • Jest
Source: https://raygun.com/blog/javascript-unit-testing-frameworks/

Why Jest?

Jest is used and recommended by Facebook and officially supported by the React dev team.

It has a great community and active support, so if you run into a problem and can’t find a solution in the comprehensive documentation, there are thousands of developers out there who could help you figure it out within hours.

1. Performance: Ideal for larger projects with continuous deployment needs, Jest delivers enhanced performance.

2. Compatibility: While Jest is widely used for testing React applications, it seamlessly integrates with other frameworks like Angular, Node, Vue, and Babel-based projects.

3. Auto Mocking: Jest automatically mocks imported libraries in test files, reducing boilerplate and facilitating smoother testing workflows.

4. Extended API: Jest comes with a comprehensive API, eliminating the necessity for additional libraries in most cases.

5. Timer Mocks: Featuring a Time mocking system, Jest accelerates timeout processes, saving valuable testing time.

6. Active Development & Community: Jest undergoes continuous improvement, boasting the most active community support for rapid issue resolution and updates.

Components of a test case in Jest

Describe

  • As the name indicates, they are responsible for describing the module we are going to test.
  • It should only describe the module, not the tests, as this describe module is generally not tested by Jest.

It

  • Here, the actual code is tested and verified with actual or fake (spy, mocks) outputs.
    We can nest various it modules under the describe module.
  • It’s good to describe what the test does or doesn’t do in the description of the it module.

Matchers

  • Matchers match the output with a real/fake output.
  • A test case without a matcher will always be a true/trivial test case.

// For each unit test you write,
// answer these questions:
describe('What component aspect are you testing?', () => {
it('What should the feature do?', () => {
const actual = 'What is the actual output?'
const expected = 'What is the expected output?'
expect(actual).toEqual(expected) // matcher
})
})
view raw node.js hosted with ❤ by GitHub

Mocks and spies in Jest

Mocks: They are objects or functions that simulate the behavior of real components. They are used to create controlled environments for testing by replacing actual components with simulated ones. Mocks are employed to isolate the code being tested, ensuring that the test focuses solely on the unit or component under examination without interference from external dependencies.

It is mainly used for mocking a library or function that is most frequently used in the whole file or unit test case.

Let Code.ts be the file you want to test.

import { v4 as uuidv4 } from uuid
export const functionToTest = () => {
const id = uuidv4()
// rest of the code
return id;
}
view raw node.js hosted with ❤ by GitHub

As this is a unit test, we won't be testing the uuidV4 function, so we will mock the whole uuid module using jest.mock.

jest.mock('uuid', () => { uuidv4: () => 'random id value' })) // mocking uuid module which will have uuidV4 as function
describe('testing code.ts', () => {
it('i have mocked uuid module', ()=> {
const res = functionToTest()
expect(res).tobeEqual('random id value')
})
})
view raw node.js hosted with ❤ by GitHub

And that's it. You have mocked the entire uuid module, so when it is coded during a test, it will return uuidV4 function, and that function, when executed, will give a random id value.

Spies: They are functions or objects that "spy" on other functions by tracking calls made to them. They allow you to observe and verify the behavior of functions during testing. Spies are useful for checking if certain functions are called, how many times they are called, and with what arguments. They help ensure that functions are interacting as expected.

This is by far the most used method, as this method works on object values and thus can be used to spy class methods efficiently.

class DataService {
fetchData()
{
// code to fetch data
return { 'real data'}
}
}
view raw node.js hosted with ❤ by GitHub

describe('DataService Class', () => {
it('should spy on the fetchData method with mockImplementation', () => {
const dataServiceInstance = new DataService();
const fetchDataSpy = jest.spyon(DataService.prototype, 'fetchData'); // prototype makes class method to a object
fetchDataSpy.mockImplementation(() => 'Mocked Data'); // will return mocked data whenever function will be called
const result = dataServiceInstance.fetchData(); // mocked Data
expect(fetchDataSpy).toHaveBeenCalledTimes(1)
expect(result).toBe('Mocked Data');
}
}
view raw node.js hosted with ❤ by GitHub

Mocking database call

One of the best uses of Jest is to mock a database call, i.e., mocking create, put, post, and delete calls for a database table.

We can complete the same action with the help of only Jest spies.

Let us suppose we have a database called DB, and it has lots of tables in it. Let’s say it has Table Student in it, and we want to mock create a Student database call.

function async AddStudent(student: Student)
{
await db.Student.create(student) // the call we want to mock
}
view raw node.js hosted with ❤ by GitHub

Now, as we are using the Jest spy method, we know that it will only be applicable to objects, so we will first make the Db. Students table into an object with create as method inside it, which will be jest.fn() (a function which can be used for mocking functions).

Students an object with create as method inside object which will be jest.fn() (a function which can be used for mocking functions in one line without actually calling that function).

describe('mocking data base call', () => {
it('mocking create function', async () => {
db.Student = {
create: jest.fn()
}
const tempStudent = {
name: 'john',
age: '12',
Rollno: 12
}
const mock = jest.spyon(db.Student, 'create').
mockResolvedvalue('Student has been created successfully')
await AddStudent(tempStudent)
expect(mock).tohaveBeenCalledwith(tempStudent);
})
})
view raw node.js hosted with ❤ by GitHub

Testing private methods

Sometime, in development, we write private code for classes that can only be used within the class itself. But when writing test cases, we call the function by creating a class instance, and the private functions won’t be accessible to us, so we will not be able to test private functions.

But in core JavaScript, there is no concept of private and public functions; it is introduced to us as TypeScript. So, we can actually test the private function as a normal public function by using the //@ts-ignore comment just above calling the private function.

class Test()
{
private private_fun() {
console.log("i am in private function");
return "i am in private function"
}
}
view raw node.js hosted with ❤ by GitHub

describe('Testing test class', () => {
it('testing private function', () => {
const test = new Test()
//calling code with ts-ignore comment
//@ts-ignore
const res = test.private_fun() // output ->> "i am in private function "//
expect(res).toBeEqual("i am in private function")
})
})
view raw node.js hosted with ❤ by GitHub

P.S. One thing to note is that this will only work with TypeScript/JavaScript files.

The importance of test cases in software development

Makes code agile:

In software development, one may have to change the structure or design of your code to add new features. Changing the already-tested code can be risky and costly. When you do the unit test, you just need to test the newly added code instead of the entire program.

Improves code quality:

A lot of bugs in software development occur due to unforeseen edge cases. If you forget to predict a single input, you may encounter a major bug in your application. When you write unit tests, think carefully about the edge cases of every function in your application.

Provides Documentation:

The unit test gives a basic idea of what the code does, and all the different use cases are covered through the program. It makes documentation easier, increasing the readability and understandability of the code. Anytime other developers can go through the unit test interface, understand the program better, and work on it fast and easily.

Easy Debugging:

Unit testing has made debugging a lot easier and quicker. If the test fails at any stage, you only need to debug the latest changes made in the code instead of the entire program. We have also mentioned how unit testing makes debugging easier at the next stage of integration testing as well.

Conclusion

So, if you made it to the end, you must have some understanding of the importance of test cases in your code.

We’ve covered the best framework to choose from and how to write your first test case in Jest. And now, you are more confident in proving bug-free, robust, clean, documented, and tested code in your next MR/PR.

Get the latest engineering blogs delivered straight to your inbox.
No spam. Only expert insights.
Thank you! Your submission has been received!
Oops! Something went wrong while submitting the form.
Thank you! Your submission has been received!
Oops! Something went wrong while submitting the form.

Did you like the blog? If yes, we're sure you'll also like to work with the people who write them - our best-in-class engineering team.

We're looking for talented developers who are passionate about new emerging technologies. If that's you, get in touch with us.

Explore current openings

You may also like

No items found.

Beginner’s Guide for Writing Unit Test Cases with Jest Framework

Prerequisite

Basic JavaScript, TypeScript

Objective

To make the reader understand the use/effect of test cases in software development.

What’s in it for you?

In the world of coding, we're often in a rush to complete work before a deadline hits. And let's be honest, writing test cases isn't usually at the top of our priority list. We get it—they seem tedious, so we’d rather skip this extra step. But here's the thing: those seemingly boring lines of code have superhero potential. Don't believe me? You will.

In this blog, we're going to break down the mystery around test cases. No jargon, just simple talk. We'll chat about what they are, explore a handy tool called Jest, and uncover why these little lines are actually the unsung heroes of coding. So, let's ditch the complications and discover why giving some attention to test cases can level up our coding game. Ready? Let's dive in!

What are test cases?

A test case is a detailed document specifying conditions under which a developer assesses whether a software application aligns with customer requirements. It includes preconditions, the case name, input conditions, and expected results. Derived from test scenarios, test cases cover both positive and negative inputs, providing a roadmap for test execution. This one-time effort aids future regression testing.

Test cases offer insights into testing strategy, process, preconditions, and expected outputs. Executed during testing, they ensure the software performs its intended tasks. Linking defects to test case IDs facilitates efficient defect reporting. The comprehensive documentation acts as a safeguard, catching any oversights during test case execution and reinforcing the development team's efforts.

Different types of test cases exist, including integration, functional, non-functional, and unit.
For this blog, we will talk about unit test cases.

What are unit test cases?

Unit testing is the process of testing the smallest functional unit of code. A functional unit could be a class member or simply a function that does something to your input and provides an output. Test cases around those functional units are called unit test cases.

Purpose of unit test cases

  • To validate that each unit of the software works as intended and meets the requirements:
    For example, if your requirement is that the function returns an object with specific properties, a unit test will detect whether the code is written accordingly.
  • To check the robustness of code:
    Unit tests are automated and run each time the code is changed to ensure that new code does not break existing functionality.
  • To check the errors and bugs beforehand:
    If a case fails or doesn’t fulfill the requirement, it helps the developer isolate the area and recheck it for bugs before testing on demo/UAT/staging.

Different frameworks for writing unit test cases

There are various frameworks for unit test cases, including:

  • Mocha
  • Storybook
  • Cypress
  • Jasmine
  • Puppeteer
  • Jest
Source: https://raygun.com/blog/javascript-unit-testing-frameworks/

Why Jest?

Jest is used and recommended by Facebook and officially supported by the React dev team.

It has a great community and active support, so if you run into a problem and can’t find a solution in the comprehensive documentation, there are thousands of developers out there who could help you figure it out within hours.

1. Performance: Ideal for larger projects with continuous deployment needs, Jest delivers enhanced performance.

2. Compatibility: While Jest is widely used for testing React applications, it seamlessly integrates with other frameworks like Angular, Node, Vue, and Babel-based projects.

3. Auto Mocking: Jest automatically mocks imported libraries in test files, reducing boilerplate and facilitating smoother testing workflows.

4. Extended API: Jest comes with a comprehensive API, eliminating the necessity for additional libraries in most cases.

5. Timer Mocks: Featuring a Time mocking system, Jest accelerates timeout processes, saving valuable testing time.

6. Active Development & Community: Jest undergoes continuous improvement, boasting the most active community support for rapid issue resolution and updates.

Components of a test case in Jest

Describe

  • As the name indicates, they are responsible for describing the module we are going to test.
  • It should only describe the module, not the tests, as this describe module is generally not tested by Jest.

It

  • Here, the actual code is tested and verified with actual or fake (spy, mocks) outputs.
    We can nest various it modules under the describe module.
  • It’s good to describe what the test does or doesn’t do in the description of the it module.

Matchers

  • Matchers match the output with a real/fake output.
  • A test case without a matcher will always be a true/trivial test case.

// For each unit test you write,
// answer these questions:
describe('What component aspect are you testing?', () => {
it('What should the feature do?', () => {
const actual = 'What is the actual output?'
const expected = 'What is the expected output?'
expect(actual).toEqual(expected) // matcher
})
})
view raw node.js hosted with ❤ by GitHub

Mocks and spies in Jest

Mocks: They are objects or functions that simulate the behavior of real components. They are used to create controlled environments for testing by replacing actual components with simulated ones. Mocks are employed to isolate the code being tested, ensuring that the test focuses solely on the unit or component under examination without interference from external dependencies.

It is mainly used for mocking a library or function that is most frequently used in the whole file or unit test case.

Let Code.ts be the file you want to test.

import { v4 as uuidv4 } from uuid
export const functionToTest = () => {
const id = uuidv4()
// rest of the code
return id;
}
view raw node.js hosted with ❤ by GitHub

As this is a unit test, we won't be testing the uuidV4 function, so we will mock the whole uuid module using jest.mock.

jest.mock('uuid', () => { uuidv4: () => 'random id value' })) // mocking uuid module which will have uuidV4 as function
describe('testing code.ts', () => {
it('i have mocked uuid module', ()=> {
const res = functionToTest()
expect(res).tobeEqual('random id value')
})
})
view raw node.js hosted with ❤ by GitHub

And that's it. You have mocked the entire uuid module, so when it is coded during a test, it will return uuidV4 function, and that function, when executed, will give a random id value.

Spies: They are functions or objects that "spy" on other functions by tracking calls made to them. They allow you to observe and verify the behavior of functions during testing. Spies are useful for checking if certain functions are called, how many times they are called, and with what arguments. They help ensure that functions are interacting as expected.

This is by far the most used method, as this method works on object values and thus can be used to spy class methods efficiently.

class DataService {
fetchData()
{
// code to fetch data
return { 'real data'}
}
}
view raw node.js hosted with ❤ by GitHub

describe('DataService Class', () => {
it('should spy on the fetchData method with mockImplementation', () => {
const dataServiceInstance = new DataService();
const fetchDataSpy = jest.spyon(DataService.prototype, 'fetchData'); // prototype makes class method to a object
fetchDataSpy.mockImplementation(() => 'Mocked Data'); // will return mocked data whenever function will be called
const result = dataServiceInstance.fetchData(); // mocked Data
expect(fetchDataSpy).toHaveBeenCalledTimes(1)
expect(result).toBe('Mocked Data');
}
}
view raw node.js hosted with ❤ by GitHub

Mocking database call

One of the best uses of Jest is to mock a database call, i.e., mocking create, put, post, and delete calls for a database table.

We can complete the same action with the help of only Jest spies.

Let us suppose we have a database called DB, and it has lots of tables in it. Let’s say it has Table Student in it, and we want to mock create a Student database call.

function async AddStudent(student: Student)
{
await db.Student.create(student) // the call we want to mock
}
view raw node.js hosted with ❤ by GitHub

Now, as we are using the Jest spy method, we know that it will only be applicable to objects, so we will first make the Db. Students table into an object with create as method inside it, which will be jest.fn() (a function which can be used for mocking functions).

Students an object with create as method inside object which will be jest.fn() (a function which can be used for mocking functions in one line without actually calling that function).

describe('mocking data base call', () => {
it('mocking create function', async () => {
db.Student = {
create: jest.fn()
}
const tempStudent = {
name: 'john',
age: '12',
Rollno: 12
}
const mock = jest.spyon(db.Student, 'create').
mockResolvedvalue('Student has been created successfully')
await AddStudent(tempStudent)
expect(mock).tohaveBeenCalledwith(tempStudent);
})
})
view raw node.js hosted with ❤ by GitHub

Testing private methods

Sometime, in development, we write private code for classes that can only be used within the class itself. But when writing test cases, we call the function by creating a class instance, and the private functions won’t be accessible to us, so we will not be able to test private functions.

But in core JavaScript, there is no concept of private and public functions; it is introduced to us as TypeScript. So, we can actually test the private function as a normal public function by using the //@ts-ignore comment just above calling the private function.

class Test()
{
private private_fun() {
console.log("i am in private function");
return "i am in private function"
}
}
view raw node.js hosted with ❤ by GitHub

describe('Testing test class', () => {
it('testing private function', () => {
const test = new Test()
//calling code with ts-ignore comment
//@ts-ignore
const res = test.private_fun() // output ->> "i am in private function "//
expect(res).toBeEqual("i am in private function")
})
})
view raw node.js hosted with ❤ by GitHub

P.S. One thing to note is that this will only work with TypeScript/JavaScript files.

The importance of test cases in software development

Makes code agile:

In software development, one may have to change the structure or design of your code to add new features. Changing the already-tested code can be risky and costly. When you do the unit test, you just need to test the newly added code instead of the entire program.

Improves code quality:

A lot of bugs in software development occur due to unforeseen edge cases. If you forget to predict a single input, you may encounter a major bug in your application. When you write unit tests, think carefully about the edge cases of every function in your application.

Provides Documentation:

The unit test gives a basic idea of what the code does, and all the different use cases are covered through the program. It makes documentation easier, increasing the readability and understandability of the code. Anytime other developers can go through the unit test interface, understand the program better, and work on it fast and easily.

Easy Debugging:

Unit testing has made debugging a lot easier and quicker. If the test fails at any stage, you only need to debug the latest changes made in the code instead of the entire program. We have also mentioned how unit testing makes debugging easier at the next stage of integration testing as well.

Conclusion

So, if you made it to the end, you must have some understanding of the importance of test cases in your code.

We’ve covered the best framework to choose from and how to write your first test case in Jest. And now, you are more confident in proving bug-free, robust, clean, documented, and tested code in your next MR/PR.

Did you like the blog? If yes, we're sure you'll also like to work with the people who write them - our best-in-class engineering team.

We're looking for talented developers who are passionate about new emerging technologies. If that's you, get in touch with us.

Explore current openings