What is Jest
Unit tests are very common in every projects nowadays, and Jest is a JavaScript testing framework designed to ensure correctness of any JavaScript codebase.
What is mocking
In a unit test, mock objects can simulate the behavior of complex, real objects and are therefore useful when a real object is impractical or impossible to incorporate into a unit test.
Mocking library functions and global methods
When writing unit tests, you might come across a lot of function that uses third-party libraries and global methods, every time you run your tests, they said those functions are “undefined” or “not yet implemented”
So today, I will write a tutorial on how to mock those functions. Here I have an example:
For context, this is a test for a function called copyImage
, its functionality is to copy a DOM element to clipboard as an image. In the function, I use a library called dom-to-image
to convert a DOM element into an image, then copy it to the clipboard.
Library’s function
We use jest.mock
to start mocking a module, then enter the module’s name, lastly we provide a callback to return the mocked module.
You can see I used requireActual
, you might ask why I imported whole library here if I’m going to mock it later ? Well because the copyImage
function only use the toBlob
method from the library, so only toBlob
need to be mocked. To convert it into a function, just use jest.fn()
. Okay, now the toBlob
method from dom-to-image
library has been mocked in this file.
Global methods
Convert the DOM element into image is just half of the story, next thing I want to copy it to the clipboard so I can paste it anywhere I want. For this functionality, I use the following code:
navigator.clipboard.write([ new ClipboardItem( Object.defineProperty({}, blob.type, { value: blob, enumerable: true, }) ),]);
So both navigator
and ClipboardItem
are global in JavaScript, they don’t belong to any of my code. If you run the test without mocking, it would said not yet implemented
for those function. So how can I mock it, let’s look at the example above:
Object.assign(navigator, {
clipboard: {
write: () => {},
},
});Object.assign(window, {
ClipboardItem: () => {},
});
I used Object.assign
to assign the functions I used as an empty function, but you can mock them into anything you want to. But not yet, we need these:
jest.spyOn(navigator.clipboard, "write");
jest.spyOn(window, "ClipboardItem");
With spyOn
methods, jest will listen when those functions are called in the test, this is useful when you want to spy on a getter or a setter, respectively.
Conclusion
My article won’t cover every cases, but I guess with most of the basic usage, you can try my approaches. Hope this article helped you !
Last Words
Although my content is free for everyone, but if you find this article helpful, you can buy me a coffee here