Using API first and TDD for your next library
Tags: tdd, testing, javascript, node
Published: 2018-12-26 23:19:50


---
title: Using API first and TDD for your next library
published: true
description: An smooth introduction to unit tests with this concept of making the api before writting some tests.
tags: tdd, testing, javascript, node
---

I used this technique to help me create more relevant unit tests, and I wanted to share it with you.

If TDD does not sound familiar to you, check this quick but straight to the point post :

{% link https://dev.to/eljayadobe/the-tdd-test-56bh %}

# TDD might not be the right tool to start with

Let us imagine we are building a node module to check if a date is between two dates. Let us call it `is-date-between`.

Let us create our unit tests right now.

...

Sounds complicated, isn't it?

# API first to the rescue

Let us take another approach: give me an example of usage for this library. 


```javascript
const isDateBetween = require('is-date-between');

const dateToCheck = new Date('2018-12-26');
const pastDate = new Date('2017-01-01');
const futureDate = new Date('2019-01-01');

console.log(isDateBetween(dateToCheck, pastDate, futureDate)); // true
```

From this we can extrapolate the different issue we want to avoid:

- the past & future date should not be reverted
- all the parameters should be date objects
- the checking should be inclusive

Which would be transcribed into:

```javascript
const chai = require('chai');
const expect = chai.expect;
const isDateBetween = require('is-date-between');

describe('isDateBetween', function() {
  it('should throw an exception if the past & future dates are reverted', function() {
    expect(function() {
      const dateToCheck = new Date('2018-12-26');
      const pastDate = new Date('2017-01-01');
      const futureDate = new Date('2019-01-01');
 
      isDateBetween(dateToCheck, futureDate, pastDate);
    }).to.throw('dates are reverted');
  });

  it('should throw an exception if the date to check is not a date object');
  it('should throw an exception if the past date is not a date object');
  it('should throw an exception if the future date is not a date object');
  it('should return true if the date to check is between');
  it('should return false if the date to check is not between');

  describe('inclusive dates', function() {
    it('should return true if the date to check is equal to the past date');
    it('should return true if the date to check is equal to the future date');
  });
});
```

See, you did it! 

# Next level: coverage & mutations testing

Testing relies on the human. By definition we are not perfect, we can forget, we can do mistakes, we can be irrelevant or repetitive...

Some tools help you limit this, until [Elon Musk have turned us into cyborgs](https://www.cnbc.com/2018/09/07/elon-musk-discusses-neurolink-on-joe-rogan-podcast.html).

**Code coverage** lets you check which part of your code is left untested. This helps you cover a maximum of cases. I like [nyc](https://www.npmjs.com/package/nyc) because it works well with [mocha](https://www.npmjs.com/search?q=mocha).

**Mutations testing** is a powerful tool to check if you tested the right parts of your code. It will change a little bit your source file and check if some tests fail: if not, you might have passed over some tests that would have not let the mutations pass through your tests. Pretty cool to help us reach a high level of quality in your unit tests. I like [stryker](https://www.npmjs.com/package/stryker) a lot.

# In conclusion

Testing in 2019 should not be scary, but accessible. I think we tend to make things a lot more complicated than they appear to be in real. I hope API first will give you the desire to start using testing if you never did before.

Testing will require a bit more time, but this is a time you will earn when scaling for more features and fixes. It can actually make you more confident over next releases of your products, because you can rely on tests to build solid basis.

If you ever thought

> Better not touch this part of the code, this is too complicated and could break if we add something.

Maybe this is the right time to think of unit tests ;).