Unit testing & integration explained with math functions 
Tags: javascript, testing, functional, beginners
Published: 2020-05-16 20:31:41

In this quick post, I hope to explain with some common math abstraction how I perceive Unit testing and Integration testing.

Disclaimer: _This is post is only meant to provide the notions behind testing, is not meant to be an in-depth testing explanation_ 😛

Okay, you must be asking yourself, why? I mean, not all coding is created equal, and let's be honest - you don't really need to understand math to code. However, I do believe that - and this comes from someone who flunked calculus and algebra numerous times in college - math is fascinating and a great tool to explain concepts in a simple manner. 

# First of all - what is a function? 📦

> A function is a process or a relation that associates each element x of a set X, the domain of the function, to a single element y of another set Y

I can't find a better definition than to look at it as a black box. A function is a _black box_ that, when given a value, will return something else.

![Alt Text](https://upload.wikimedia.org/wikipedia/commons/thumb/3/3b/Function_machine2.svg/480px-Function_machine2.svg.png)

Reference: [Wikipedia](https://en.wikipedia.org/wiki/Function_(mathematics))

Okay, cool - that's as much math as you need to know for what's next!

So here's the thing, we want to test functions. We want to make sure they return the correct value each time they're called. We have this first function `f(x)` which returns the given number `x` plus one. Then, we have `g(x, y)` which does a bit more, it returns the sum of `x` plus the result of `f(y)`.

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/rzz0dn5e6h6td2jk29lw.jpg)

What's going on here? we have one function `f(x)` that we can test by itself as it has no dependency on another function. This is what we can consider something that can be tested as a unit.

Then, there's another function `g(x, y)` which implements `f(x)`. It needs `f(x)` to produce a value. It is directly dependant and therefore needs this other function to live. _Nothing like a math love story._ 💙 

# Coding the functions 💻

So in order to actually test this, we would have to, you know, code these functions. You can use your language of choice but as the JavaScript fan I am, I highly encourage you to use js 💛

So for both functions, we will end up having something like this:

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/rjeqg3vxraynxhmq6px1.png)

# Getting into the tests 🧪️

Now that we have coded our functions, we want to test this first function `f(x)` and make sure that it returns the correct value for `x = 1` 

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/l37s5qh4tfq2hwx852g1.jpg)

We also want to test that `g(x, y)` returns a correct value for `x = 2 ; y = 1`

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/u3kfubrn07k4y4lsuaw7.jpg)

I will be using _Jest_ for these examples, if you still don't know about [Jest](https://jestjs.io/), give it a shot, it's an amazing testing framework for js!

So for the following [test suite](https://en.wikipedia.org/wiki/Test_suite) We will be expecting that when we call these functions with the params described above, they should actually return what we expect.

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/8orl66vx91a2qb3nq9bp.png)

_One thing to highlight here is that by testing `g(x, y)` we are implicitly testing `f(x)`._

# Mocking 🃏

Can we test `g(x, y)` as a unit? Up until now we now that `g(x, y)` depends on `f(x)`, so its result will be bound to the result of `f(x)`.

...or will it? 🤔

Mock is a very interesting concept when it comes to testing. For some controversial, for some a helpful tool. I am not here to discuss this, but rather give you the notion of what mocking is, and how we _could_ use it to test `g(x, y)` without any dependencies.

With mocking you can override, substitute, manage things that should be out of your control. In this example, because of how `g(x, y)` is built, we should not be able to look inside our `black box` and replace `f(x)` with something else.

This is where _mocking_ comes in. In an uncontrolled environment, it allows you to open up the `black box` and substitute parts of how the system behaves to your will.

It would be the equivalent to doing something like this:

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/y7mhjjj5aiynhlo2nung.jpg)


Now, because we have tampered with `g(x, y)`'s black box, it will produce a new output.

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/ffew13lsuvjx8cfbi0l7.jpg)

Compare that to the example above, in which we don't have access to the black box

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/u3kfubrn07k4y4lsuaw7.jpg)

These are not equal scenarios, hence why researching how to mock properly is something worth investing some time in!

So then - can we test `g(x, y)` in isolation? as a unit?

Yes! - Jest offers a lot of functionality for mocking

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/udksmf8ij74w2j1uojek.png)

⚠️ *Should you test `g(x, y)` in isolation?*

It depends - are you testing edge cases? is `f(x)` an external dependency out of your control? There are a lot of things to keep in mind before mocking.

So that's it! A basic introduction to testing explained with math functions.

Hope you liked this post - keep hacking! 🔥