Mocking Objects in TypeScript, Functional Style

Daniel Dughila
ITNEXT
Published in
2 min readDec 5, 2017

--

I like the idea of test-driven development because it makes you think about what code does instead of how it does it.

At my current workplace, I am developing a very customer facing online store application in Angular.

Even if I’m not at the TDD level yet, I try to get high test coverage for my code, avoiding late-night calls about a bug in production and possibly ruining the sleep of my little girl.

Being an online store, I’m working allot with entities like Price and Product. These are very stripped out versions of the Price and Product interfaces. In reality, the backend API returns objects with over 25 properties.

Price.ts
Product.ts

Here is a piece of code similar to what I have to test on a daily basis which uses the interfaces above.

product-utils.ts

Both filterProductsByName and addPriceToProduct are pure, curried functions, using the spread operator.

If you are interested in functional programming, I recommend watching these videos by Mattias Petter Johansson.

The code above filters products by name and adds a price to a product.

Mmmm, let’s see if it actually works!

I have implemented the tests with Jest, Mocha and of course TypeScript.

product-utils.spec

Uff, over 60 lines of test code for 14 lines of actual implementation.

This hurts my pretty, little soul!

As we are serious about tests, we need to do something about it.

This idea came to mind after reading an article on TypeScript’s Partial by Netanel Basal.

What if instead of declaring the whole Product entity, I could use a factory function which takes a Partial<Product> argument (a subset of properties belonging to the Product interface), and merges it with a set of default properties?

Even If I’m in a hurry, and decide to call getProductMock without any arguments, I’ll still get a valid default Product type object to safely use.

Product.mock.ts
Price.mock.ts

Having those fancy factories in our tool belt, let’s mock!

product-utils-with-mocks.spec

As you can see, the tests which use these mock functions are terse and less than half the size of the ones who don’t.

Here, I just need a puffy product (grrr, tend to write pussy instead :) supplying only its name. And guess what? The getProductMock method lets me get away with it, returning a valid product nonetheless.

That’s it, happy mocking!

I hope you’ve enjoyed this article and will use this simple way of mocking to your benefit!

--

--