Do you think IIT Guwahati certified course can help you in your career?
No
Introduction
In software testing, the importance of isolating individual components for rigorous examination cannot be overstated. Enter Jest Mock Objects: a powerful tool for developers, they utilize the Jest testing framework for JavaScript applications.
Mock objects serve as stand-ins for real objects during the testing process, allowing developers to simulate behavior, control inputs, and verify outputs in a controlled environment. Within the Jest ecosystem, mock objects play a pivotal role in facilitating efficient and comprehensive testing, enabling developers to write robust, reliable code with confidence.
We will understand the need to mock a function or module, and then we will create an example mock function using Jest. We will also learn about the .mock property of Jest mock functions. Finally, we will learn about mock return values. I hope you learn a lot from this article.
What is Mocking?
Mocking is one of the fundamentals of writing great unit tests.
If I have to use only one line to explain Mocking, "Mocking is replacing something that we don't control with something that we control."
So if we have a function or a module to test, instead of calling that function, we make a mock function that has the behavior of the primary function. So by mocking a function, we can capture calls of that function, provide our desired return values in our mock function, and even change the implementation of the functions and modules in the mock function.
Mocking dependencies of your code allows developers to control the function's behavior, which helps test functions and modules more efficiently and with more ease.
What is mocking in Jest?
It is clear now that mock functions are created to capture the function's behavior under test.
There are two ways to mock functions: creating a mock function in test code or writing a manual mock to override a module dependency.
We can create a mock function using Jest. fn(), we can mock a module using Jest. mock().
Why do we need Mocking?
Let's discuss a real-world example here; let's say we have a function that fetches students' marks from the student table in the database and returns the average marks of students.
Now to test this function, we wrote a test that matches returned average value with the actual average of marks, our test passes, and everything seems fine.
But the problem here is that the database is not static and constantly changing, so even a single update in the database leads to the failure of tests.
Therefore, instead of fetching data from the database or API calls, we create a mock with a custom return value per our requirement.
Also, these API calls are very time-consuming and costly; therefore, we don't want to call them every time we run a test, so mocking provides an effective way to deal with such problems.
Let's make a function in the main file that will take two parameters: check and data, we will mock its callback function.
Program
// creating functions
const functions = {
function: (check, data, callback) => {
if (check === true) {
callback(data);
}
}
}
//export the function
module.exports = functions
Now in the test file, create a mock function using Jest.fn()
Test
// importing functions
const functions = require('./function.js');
// creating mockedCallback function which is a mock of callback function passed in function.
const mockedCallback = jest.fn(parameter => parameter);
// calling main function using a mockedCallback function,
functions.function(true, 5, mockedCallback);
// testing
// mockedCallback should be called once.
test('checking if mockedCallback is called once', () => {
expect(mockedCallback).toHaveBeenCalledWith(5);
});
// mockedCallback should return 5
test('checking output of mockedCallback', () => {
expect(mockedCallback.mock.results[0].value).toBe(5);
});
Output
.mock Property in Jest
.mock is a unique property of every mock function in which metadata about the mock function calls are stored, like how the mock function is called and what the function returned contains.
We can also inspect the value of "this" using .mock.
Let's see an example program to inspect the value of the “this” keyword.
// creating mock function called myMock
const myMock = jest.fn();
// instance1 is of type myMock
const instance1 = new myMock();
// instance2 is not of type myMock
const instance2 = {};
// The bind() method creates a new function with the "this" keyword set to the provided value.
const bound = myMock.bind(instance2);
bound();
// .mock.instances contains all the instances of myMock.
test('checking if myMock has 2 instances and printing them in console', () => {
//console.log all instances of myMock
console.log(myMock.mock.instances);
// To check the count of instances of myMock function is 2
expect(myMock.mock.instances.length).toBe(2);
});
Output
Now let's see some examples of different members of .mock property.
Examples
// To check if the myMock function is called once
expect(myMock.mock.calls.length).toBe(1);
// To check all instances of myMock function
expect(myMock.mock.instances.length).toBe(2);
// To check the results returned my myMock function.
expect(myMock.mock.results[0].value).toBe(5);
There are several useful members of .mock property, that is used as per their definition, like .mock.calls, .mock.calls.length .mock.results.value, .mock.instance etc.
Mock Return value
Mock functions can also inject test values into your code during a test using a mock return value.
Let's see an example of the mock return value; it will be more precise.
Example
// creating new mock function called new_mock
const new_mock = jest.fn();
new_mock.mockReturnValueOnce(1).mockReturnValue(2);
test('checking mock return values and printing in console', () => {
// calling new_mock and printing the result in the console.
console.log(new_mock(), new_mock(), new_mock());
});
Output
Instead of printing in the console, this new_mock() function can be added anywhere in the code while writing a test.
Mocking Modules
In Jest, mocking modules entails replacing a module's actual implementation with a phoney one. This is frequently done to separate a module from its dependencies or to prevent calling outside resources while testing. In Jest, there are three primary types of mocking modules:
jest.mock: The path to the module you wish to mock is passed as an argument to this function, which then returns a module factory with which you can define the mock implementation.
jest.fn: It enables you to build a mock function. When testing, a mock function can be used in place of the actual function because it is a fake implementation of the function.
jest.spyOn: It allows you to create a spy function. A spy function is a special type of mock function that allows you to track calls to a function and access information about those calls
Mock Implementations
Jest uses the technique of mocking to replace certain sections of your code with a fake implementation so that you can test isolated functionality.
Especially when working with complicated apps or components that depend on external dependencies or services, mocking is a basic idea in software testing. To guarantee that the code being examined acts as intended, it enables you to construct controlled and isolated testing environments.
Some Jest mock implementation examples:
Jest is adaptable for many testing circumstances since it offers a variety of techniques for building fake implementations. To replicate the behavior of functions or methods in your codebase, for example, you can construct mock functions. This lets you manage their return values and observe how they are called during testing.
This example sets the return value of the myFunction function to 36 while mocking a module called myModule. This enables us to test our code without actually calling the real implementation that calls the myFunction function.
By ensuring isolation, we can limit dependencies and potential external problems and ensure that our test only examines the logic contained within the code. Such focused testing is an essential step for modern software development since it improves code quality and makes debugging easier.
For the purposes of this example, we will create a mock function called myFunction and set 36 as its return value. In order to verify that the myOtherFunction function behaves appropriately when called with myFunction, we can use this mock function in our test of the function.
You can confirm that myOtherFunction behaves as expected when using myFunction by asserting that the return value of myOtherFunction matches the return value of our mock, all within a controlled testing environment. This strategy improves the accuracy and dependability of our unit tests, which supports the development of solid code.
In the given example, we are creating an instance of a class called MyClass called myInstance after mocking it. Using this instance in our test of the myMethod function, we can set the return value of the myMethod method to be 36.
You may carefully examine myMethod's actions to make sure that they work properly with the rest of our code. This method of testing with mocks increases the precision and dependability of our tests, which eventually helps to create software that is durable and maintainable.
Frequently Asked Questions
What is Jest mocking?
Jest Mocking is a method for isolating test subjects by swapping out dependencies for manipulable objects. A dependency can be anything that your topic depends on, however, it usually refers to an imported module.
How to mock object using Jest?
To mock an object in Jest, use the jest.mock() function with the path to the module you want to mock. You can then define a mock implementation for the object's methods and properties using jest.fn().
Is Jest mocking or spying?
Jest supports both mocking and spying. Mocking involves replacing a function's implementation with a fake one, while spying allows you to observe function calls and their arguments without affecting their behavior.
What does Jest mock module do?
Jest's mock module feature allows developers to replace modules with mock implementations during testing. This enables isolation of components and control over their behavior, facilitating more robust and predictable testing scenarios.
What are the benefits of Jest testing?
Jest offers several benefits for testing JavaScript applications, including its intuitive syntax, fast and parallel test execution, built-in assertion library, support for mocking and spying, and seamless integration with popular frameworks like React and Vue.js. These features contribute to improved developer productivity and code quality.
Conclusion
In conclusion, Jest Mocking is a great tool to write efficient unit tests. It is one of the essential concepts in unit testing, we can quickly mock any function, module, etc.
jest.fn() is used to mock a function in jest. The mock members of the .mock property are instrumental in asserting how these functions get called, instantiated, or returned. We have also learned about the mock return value.
Hence learning never stops, and there is a lot more to learn. So head over to our practice platform Coding Ninjas Studio to practice top problems, attempt mock tests, read interview experiences, and much more.!