
Testing a Simple JavaScript Calculator with Jest

Creating a simple calculator application is a great way to learn JavaScript fundamentals. However, ensuring the reliability of your code through automated testing is equally important. In this tutorial, we’ll build a web-based calculator using vanilla JavaScript and write unit tests with Jest to validate its functionality.
Project Setup
First, let’s set up our project directory and initialize a new Node.js project.
mkdir simple-calculator-with-unit-tests
cd simple-calculator-with-unit-tests
npm init -y
Next, install Jest and Babel to transform our code.
npm install --save-dev jest babel-jest @babel/core @babel/preset-env
Create a Babel configuration file (.babelrc) in the root of your project:
{
"presets": ["@babel/preset-env"]
}
Update your package.json to include a test script and Jest configuration:
"scripts": {
"test": "jest"
},
"jest": {
"transform": {
"^.+\\.jsx?$": "babel-jest"
}
}
Building the Calculator
HTML
Create an index.html file to define the structure of our calculator:
CSS
Create a style.css file to style the calculator:
body {
font-family: Arial, sans-serif;
}
.calculator {
width: 200px;
margin: 100px auto;
}
.screen {
width: 100%;
height: 40px;
text-align: right;
margin-bottom: 10px;
font-size: 18px;
}
.button {
display: grid;
grid-template-columns: repeat(4, 1fr);
gap: 10px;
}
.btn {
padding: 20px;
font-size: 18px;
cursor: pointer;
}
.btn-yellow {
background-color: yellow;
}
.btn-grey {
background-color: grey;
}
.btn-equal {
background-color: green;
grid-column: span 2;
}
.btn-clear {
background-color: red;
grid-column: span 2;
}
JavaScript
Create an app.js file to implement the calculator functionality:
import { updateScreenValue, clearScreen, calculateExpression } from './calculator.js';
(function () {
let screen = document.querySelector(".screen");
let buttons = document.querySelectorAll(".btn");
let clear = document.querySelector(".btn-clear");
let equal = document.querySelector(".btn-equal");
buttons.forEach(function (button) {
button.addEventListener("click", function (e) {
let value = e.target.dataset.num;
if (value !== undefined) {
updateScreenValue(screen, value);
}
});
});
equal.addEventListener("click", function (e) {
calculateExpression(screen);
});
clear.addEventListener("click", function (e) {
clearScreen(screen);
});
})();
Create a calculator.js file to define the calculator functions:
export function updateScreenValue(screen, value) {
screen.value += value;
}
export function clearScreen(screen) {
screen.value = "";
}
export function calculateExpression(screen) {
if (screen.value === "") {
screen.value = "Please enter";
} else {
const isValidExpression = /^[0-9+\-*/.]+$/.test(screen.value) && !/[+\-*/.]$/.test(screen.value);
if (isValidExpression) {
try {
let answer = eval(screen.value);
screen.value = answer;
} catch (error) {
screen.value = "Error";
}
} else {
screen.value = "Error";
}
}
}
Writing and Running Unit Tests with Jest
Automated testing ensures that your code works as expected and helps catch bugs early. We will write unit tests for our calculator functions using Jest.
Create a calculator.test.js file to write unit tests:
import { updateScreenValue, clearScreen, calculateExpression } from './calculator.js';
describe('Calculator functions', () => {
let screen;
beforeEach(() => {
screen = { value: "" };
});
test('should update screen value', () => {
updateScreenValue(screen, "5");
expect(screen.value).toBe("5");
});
test('should clear screen', () => {
screen.value = "123";
clearScreen(screen);
expect(screen.value).toBe("");
});
test('should calculate expression correctly', () => {
screen.value = "2+3*4";
calculateExpression(screen);
expect(screen.value).toBe(14);
});
test('should handle empty screen', () => {
calculateExpression(screen);
expect(screen.value).toBe("Please enter");
});
test('should handle invalid expression', () => {
screen.value = "2+3*";
calculateExpression(screen);
expect(screen.value).toBe("Error");
});
});
Running Tests
Run the tests using the following command:
npm test
You should see the results of the tests, confirming that your calculator functions as expected. Here’s what each test does:
- Update Screen Value: Ensures the screen value updates correctly when a button is pressed.
- Clear Screen: Verifies that the clear button resets the screen.
- Calculate Expression: Checks that valid expressions are calculated correctly.
- Handle Empty Screen: Ensures a message is displayed when trying to evaluate an empty screen.
- Handle Invalid Expression: Confirms that invalid expressions are handled gracefully and show an error message.

Conclusion
In this tutorial, we built a simple JavaScript calculator and added unit tests with Jest to ensure its functionality. Writing tests not only helps in verifying that your code works as intended but also makes future code changes safer and easier. By integrating automated testing into your development workflow, you can create more reliable and maintainable applications.
You can find the complete code for this project on GitHub: simple-calculator-with-unit-tests.
Happy coding!