Mock functions, also known as spies, are special functions that allow us to track how a particular function is called by external code.
By using mock functions, we can know the following:
- The number of calls it received.
- Argument values used on each invocation.
- The “context” or this value on each invocation.
- How the function exited and what values were produced.
- We can also provide an implementation to override the original function behavior. And we can describe specific return values to suit our tests.
We can use mock functions when
- we want to replace a specific function return value.
- when we want to check if our test subject is executing a function in a certain way.
We can mock a standalone function or an external module method, and we can provide a specific implementation.
For example:
Let's say you are testing a business logic module that uses another module to make requests to an external API. You can then mock the functions of the dependency to avoid hitting the API on your tests. You can then run your tests, knowing what the mocked functions will return to your test subject.
The fact that we can provide an implementation to external dependencies is useful because it allows us to isolate our test subject. We can focus on it. The unit tests would focus entirely on the business logic, without needing to care about the external API.
There are several ways to create mock functions.
- The
jest.fn
method allows us to create a new mock function directly. - If you are mocking an object method, you can use
jest.spyOn
. - If you want to mock a whole module, you can use
jest.mock
.
Higher-order functions
are functions that operate on other functions. Either by receiving them as arguments or returning them as values. In the previous example, we can say that greetWorld is a higher-order function, because it expects a function as an input argument
Functions Are First-class Citizens
In JavaScript, functions can be treated just like any value. You can pass them as arguments to other functions, they can be assigned as properties of objects (as methods), or you can return other functions from them. Internally, functions are just special objects that can you can invoke.