How to mock a dependency with Jest
With React Testing Library and Jest we can use a Test Driven Development (TDD) approach when writing a React application. When coming from a C# background and being familiar with libraries such as NUnit and Moq, the syntax for mocking dependencies with Jest can take a little getting used to.
Let's take a look at a simple example.
We will create an OrderCalculatorService class and implement some functionality to calculate an order total when given a SKU and a number of units. We will of course write the test first before implementing any of the logic. The OrderCalculatorService will need to know the price of the SKU so we will create a PriceService class, introducing a dependency to this in OrderCalculatorService. When implemented, PriceService will fetch the price for a SKU from an API.
We want to mock the dependency on PriceService in our OrderCalculatorService tests and we also don't want to have to implement the functionality in PriceService yet as we're concentrating on implementing OrderCalculatorService, so we stub PriceService like this:
Next, we add our OrderCalculatorService class and test which initially look like this:
If we were to run the test now, as expected we would get an error when getPrice is called.
OK, so now we want to mock the PriceService dependency with Jest. Using the mock function we can mock a module and provide an implementation. We can return an object literal as the implementation of PriceService, specifying any functions or properties we want to mock. For this example, we will mock the getPrice function using Jest's fn function. The mocked getPrice function returns the price depending on the SKU being passed through.
Now when we run the tests we get the following
So what's happening here? The mock implementation of PriceService is returning an object literal which OrderCalculatorService is attempting to instantiate with the new keyword, this it can't do. We therefore wrap the object literal we returning for our mocked implementation of PriceService in a function, this acts as a constructor function.
Note the mock implementation must return a function declaration and not an arrow function as arrow functions can't be called with the new keyword.
The test can now be run and passes and we have successfully mocked a dependency using Jest. In my next article I show how you can provide different