TypeScript Testing Tips - Mocking Functions With Jest
Tips for mocking functions using TypeScript and Jest...
Join the DZone community and get the full member experience.Join For Free
Jest is a popular testing framework that covers all aspects of testing including mocking, verifying expectations, parallel test execution and code coverage reports. It's also light on configuration so there's a lot to like.
For more testing tips with TypeScript, check out the first article in this series.
Mocking Simple Functions
Let's say the code your testing calls out to the following helper function in a file called
For unit testing, you'll need a
sterlingToEuros, which allows you to:
- Control how the function behaves during tests via methods like
- Verify how your code interacted with the mock using, for example, to verify expectations.
To create the
MockedFunction you need to mock the module containing the function:
Now, during test execution
sterlingToEuros is a Jest
MockedFunction, but TypeScript doesn't know this at compile-time, so you're not getting the benefits of static-typing during development.
You can cast it to the correct type with:
But this is a bit long-winded, error-prone, and could detract from what's important in the test. Bear in mind, also, that many functions will have a more complex signature perhaps having multiple parameters, custom types, generics or
async, and so the above approach could get really cumbersome.
TypeScript's type inference allows us to clean this up if we add the following helper:
It probably makes sense to add this in a
JestHelpers.ts file, and future posts will show other useful helper functions that could live alongside it.
You can now use this helper in your tests as follows:
eliminating the need to include a lengthy function signature. Your mock will have the correct type and you can use it as expected:
The compiler will ensure you don't make any type errors, for example:
How it Works
That covers the main takeaway of the post, but if you're interested in how the helper works, then read on.
mockFunction simply casts a Jest
MockedFunction to the correct type. Because it uses a generic type for the input parameter it has access to the type of function being mocked and it uses this in the return type and in the implementation for casting. Here it is again:
Notice how we've restricted the types that can be passed in by stipulating:
Breaking this down:
(fn: T): The parameter is of type
T extends: The type
Tmust be compatible with
(...args: any) => any: A function, where
...args: Rest parameters are used so the function can take any number of arguments
any: The input parameters can have any type
=> any: The function can have any return type.
These restrictions on the input parameter prevent us from errors such as:
Giving us further type-safety and leveraging the strengths of TypeScript so developers are alerted to errors at the earliest possible moment.
We've now covered creating dummy objects and mocking functions with TypeScript. In future posts, we'll continue to build on this to show how we mock classes, constant objects, and object getter and setters.
Published at DZone with permission of Eoin Mullan. See the original article here.
Opinions expressed by DZone contributors are their own.