Photo by Paul Esch-Laurent on Unsplash

TDD with JavaScript Using Jest

Jonathan Reeves
9 min readSep 7, 2021

Hello, in this article I want to walk you through a basic program to give a brief example of using TDD with the Jest framework. We will start by making sure everything we need is installed and then we will jump right in. The problem chosen for this article has been solved the world over. It is a very common challenge on many sites such as Hacker Rank and Code Wars. Before diving into the challenge let’s make sure we have what we need to solve it.

Setting Up Our Environment

First and foremost in order to do any of this we will need to install a few programs. First up we will need node. Open up your terminal/cmd application and type in

node -v
// you should get
v14.15.5 // => As long as you have a version of 8.x.x or higher 👍

If the above command produces an error saying something along the lines of

node is not a command recognized...

Installing Node

Then head on over to Node and click on the button to download Node with LTS. You can download the current version however it usually brings a lot of bugs along with it. So the recommended version is the LTS one.

With Node installed we can now verify by running the same command as above in your terminal/cmd:

node -v
v14.17.6 // latest LTS version of Node as of writing

Installing a Text Editor

We will now download and install text editor. If you already have one that you prefer then I recommend just sticking with that one. However if you are new to programming or still looking for a text editor that you really like I would definitely recommend VS Code from Microsoft. It is a free and open source editor that has a ton of extensions to really make your editor your own. I use it daily for work as well as a personal programs. You can download it here. Once there you will just need to click the Blue button and download it for your operating system. Click through the install wizard and you are good to go.

Note: For Windows users you might be asked to check a box that says add to path. You will want to do this so you can run some of the commands I use in the terminal.

Project Setup

Now we can get to the good stuff. We have Node installed and have verified that it works. We have a text editor to write our code in. Let’s get started. We will run a few commands to set up our project and get going. The commands are:

cd Desktop
mkdir test-with-jest
cd test-with-jest
code .

To quickly go over what the commands are doing:

  1. cd Desktop : is changing our directory to the desktop.
  2. mkdir test-with-jest : is creating a directory named test-with-jest
  3. cd test-with-jest : is changing into the newly created directory
  4. npm init -y : this initializes a npm project and creates a package.json file
  5. npm install — save-dev jest : this installs jest as a dev dependency so that if you push up your code to production jest isn’t required.
  6. code . : this is opening our current directory inside of VS Code.

We should now have our project set up and the directory(folder) opened in a new instance of VS Code. We are now ready to write our first bit of code.

Updating package.json

We need to add a script command to easily run our tests. Open up the package.json file and you should see a section labeled “scripts”. We are going to modify the boilerplate example that it gave us. Leave the “test” : but the echo … remove that and replace it with the following:

"test": "jest --watchAll"

Save the file and we are now ready to write our first bit of tests.

Seeing Red

We will create two files. index.js and index.test.js we shouldn’t need any more files right now. If you decide you want to push this up to GitHub I will have a section at the end showing you what you need to do in order to not push up so many files.

Open up index.test.js and let’s write the following:

const fizzBuzz = require('./index');describe('fizzBuzz()', () => {
it('returns "FizzBuzz" for multiples of 3 and 5', () => {
expect(fizzBuzz(15)).toBe('FizzBuzz');
expect(fizzBuzz(30)).toBe('FizzBuzz');
});

Now from within in VS Code, open the terminal you can do this quickly by pressing ctrl + ` or you can just go to view -> terminal and a new instance will open up towards the bottom of your editor. We now need to run the test to make sure that everything works correctly. We will run the following:

npm test

This command runs the test script we set up in our package.json file. We should now see that it fails. Normally seeing red in our terminal prompt is a sign something has gone wrong. However in the case of TDD it’s actually a good sign. That means that our test is running correctly and we can now write the code that will change it from red to green.

Going Green

Now that we have our test case and it’s failing(seeing red) we can now open up index.js to write the code that will make it pass. I want you to think about the problem first. What is it that we are trying to accomplish? We aren’t solving the entire problem of FizzBuzz. Just the first case. Let’s write out some pseudo code on how we can solve this:

// function for fizzBuzz with a parameter
// our check for our test case
// return our parameter

We are going to write this out using arrow functions. If this code doesn’t make sense or look familiar to you then you may need to read up on some of the newest ES2015 features of JavaScript. Or ES6 as some people refer to it. For now let’s write our passing code:

module.exports = (num) => {
if (num % 15 === 0) return 'FizzBuzz';
return `${num}`
}

Once we save the file our test script should see that there have been changes in the source file and rerun. Changing the red to green. Isn’t that awesome. We just wrote a test, saw that it was red, and then wrote the minimal amount of code to change it green. We wrote four lines of code if you count the brace at the bottom. Four lines of code made our first test pass. Pretty awesome right?

Writing Our Next Test Case

Now we are going to handle the next case. Let’s open up the index.test.js file:

// So far we have:
const fizzBuzz = require('./index');
describe('fizzBuzz()', () => {
it('returns "FizzBuzz" for multiples of 3 and 5', () = {
expect(fizzBuzz(15)).toBe('FizzBuzz');
expect(fizzBuzz(30)).toBe('FizzBuzz');
});
// our next case here

Let’s think about this for a few minutes. We know that we have a few more cases left. But what happens if we don’t get 3 or 5? What do we do then? Well per the instructions of the FizzBuzz problem we want to return those values that are not divisible by 3 or 5 as just those numbers. So let’s write a test that handles the use case of NOT being divisible by 3 or 5.

// So far we have:
const fizzBuzz = require('./index');
describe('fizzBuzz()', () => {
it('returns "FizzBuzz" for multiples of 3 and 5', () = {
expect(fizzBuzz(15)).toBe('FizzBuzz');
expect(fizzBuzz(30)).toBe('FizzBuzz');
});
it('returns the given number not divisible by 3 or 5', () => {
expect(fizzBuzz(2)).toBe('2');
expect(fizzBuzz(32)).toBe('32');
});

Now we should see our test script rerun and technically we already solved for this as our function returns ${num} so there should now be 2 passing tests. Congratulations. We now have two passing tests. We are making some good progress here.

Challenge

I don’t normally do a challenge but for this case since this is such a commonly used coding challenge for interviews as well as just practice sites mentioned above I want to see if you can write the last two test cases and the passing code to go from red to green. Currently we have two passing tests so that means that we are going from green to red back to green. I have added the solution for both files below. Try to complete them on your own before looking at the solution. If you get stuck then and only then show the solution and see if you were on the right track with what you were trying out.

DO NOT LOOK PAST THIS POINT: Please try to solve the challenge on your own first before going any further. I know sometimes it’s hard and you just want to go directly to the solution but I promise you, just like in school when the teacher would tell you not to copy off some one else for the homework assignments because the information won’t stick. This is a similar situation. If you jump directly to the solution there is a chance that the information there won’t stick. But if you try solving the issue yourself it will benefit you in the long run. I have been there. I promise you. It will be worth trying the challenge out yourself.

index.test.js:

const fizzBuzz = require('./index');describe('fizzBuzz()', () => {
it('returns "FizzBuzz" for multiples of 3 and 5', () => {
expect(fizzBuzz(15)).toBe('FizzBuzz');
expect(fizzBuzz(30)).toBe('FizzBuzz');
});
it('returns the given number not divisible by 3 or 5', () => {
expect(fizzBuzz(2)).toBe('2');
expect(fizzBuzz(32)).toBe('32');
});
// solution to multiples of 3
it('returns the word "Fizz" for multiples of 3', () => {
expect(fizzBuzz(3)).toBe('Fizz');
expect(fizzBuzz(9)).toBe('Fizz');
});
// solution to multiples of 5
it('returns the word "Buzz" for multiples of 5', () => {
expect(fizzBuzz(5)).toBe('Buzz');
expect(fizzBuzz(25)).toBe('Buzz');
});
};

index.js

module.exports = (num) => {
if (num % 15 === 0) return 'FizzBuzz';
if (num % 3 === 0) return 'Fizz';
if (num % 5 === 0) return 'Buzz';
return `${num}`;
}

Add to Git

The last section of this article will show you how to set up your project with Git. I am not going to go into detail on what Git is. If you don’t know I highly recommend using your favorite search engine to learn more. It is an indispensable tool by any developer and you will use it daily.

To get started we need to run a few commands in our terminal.

// press ctrl + c if your test script is still running
git init // this initializes the project as a Git repo.
touch .gitignore // this creates a file that ignores certain files and directories within your project that you don't want to add to source control.

Next open up your .gitignore file and add this line to the top and save the file

node_modules/

Now we can go back to our terminal and finish the last bit of commands

git add . // this will add the files to git
git commit -m "initial commit"

That is all the commands you will need to use Git locally. If you want to add the project to a GitHub account(highly recommend) then follow these steps. The next section is optional for those that don’t want to use GitHub.

Pushing to GitHub

In order to make use of GitHub you will need an account. I highly recommend creating one as most professional development will have you use GitHub or some other Version Control repo like it. Head over to this link and create an account if you don’t have one. Once done. Use the + button at the top right of the page to select new repository and then in the name field, name your repo whatever you want. Click the create button at the bottom of the page.

You will be redirected to another page with steps to follow for pushing up your code. You will be looking for the section pushing an existing repo. Follow those steps. Once finished refresh the page and you should see a similar folder structure to what you see within VS Code.

Conclusion

I hope that this solution not only helped you solve the common FizzBuzz problem but also helped you better understand the Jest testing library as well as how to use the TDD approach to all of your coding needs. If you liked this article and want to read more about TDD please let me know.

--

--

Jonathan Reeves
Jonathan Reeves

Written by Jonathan Reeves

I am a software engineer that is currently trying to break into the DevOps world using Python. Professionally I use JavaScript with React to build websites.

No responses yet