Jest Custom Matcher: toBeInstanceOf
You're tasked with extending Jest's assertion capabilities by creating a custom matcher, toBeInstanceOf. This matcher will allow developers to assert that a received value is an instance of a specific class or constructor function, mirroring Jest's built-in expect.any() and expect.objectContaining() but with a focus on class instantiation.
Problem Description
The goal is to implement a custom Jest matcher named toBeInstanceOf. This matcher should take a constructor function or class as an argument and return true if the received value is an instance of that constructor/class, and false otherwise.
Key Requirements:
- The matcher should be named
toBeInstanceOf. - It must accept one argument: the constructor function or class to check against.
- It should return
trueifreceived instanceof constructorevaluates totrue. - It should return
falseotherwise. - The matcher should provide informative error messages when an assertion fails.
Expected Behavior:
When used in a Jest test:
expect(new MyClass()).toBeInstanceOf(MyClass); // Should pass
expect({}).toBeInstanceOf(MyClass); // Should fail
expect(null).toBeInstanceOf(MyClass); // Should fail
expect(undefined).toBeInstanceOf(MyClass); // Should fail
Examples
Example 1:
// In your test file:
class Dog {}
const myDog = new Dog();
expect(myDog).toBeInstanceOf(Dog);
Output: The assertion passes.
Explanation: myDog is indeed an instance of the Dog class.
Example 2:
// In your test file:
class Cat {}
const myDog = new Dog(); // Assuming Dog class from Example 1
expect(myDog).toBeInstanceOf(Cat);
Output: The assertion fails. The error message should indicate that myDog is not an instance of Cat.
Explanation: myDog is an instance of Dog, not Cat.
Example 3:
// In your test file:
class Animal {}
const notAnInstance = {}; // A plain object
expect(notAnInstance).toBeInstanceOf(Animal);
Output: The assertion fails. The error message should indicate that notAnInstance is not an instance of Animal.
Explanation: A plain JavaScript object is not an instance of the Animal class.
Constraints
- The solution must be implemented in TypeScript.
- The custom matcher should be compatible with Jest's testing framework.
- The constructor function passed to
toBeInstanceOfwill always be a valid function or class. - The
receivedvalue can be any JavaScript type.
Notes
- You will need to register your custom matcher with Jest. Refer to the Jest documentation on Extending Jest for guidance on how to do this.
- Consider how to provide clear and helpful error messages for both the passing and failing cases. Jest's custom matcher API provides methods like
messageandnegatedMessagefor this purpose. - Think about the core JavaScript operator that can be used to check for instance relationships.