myHotTake

Tag: JavaScript testing

  • How to Write Your First JavaScript Test with Jest or Mocha

    If you enjoy this story and find it helpful, feel free to like or share it with anyone who might be embarking on their own coding adventure!


    I’m a detective in the city of JavaScriptopolis, where mysteries and problems lurk in every snippet of code. One day, I’m tasked with solving a curious case: ensuring that a new algorithm designed to solve a problem actually works as intended. This is where I summon the power of Jest, my trusty magnifying glass, or Mocha, my reliable notebook, to write my very first test.

    I begin my investigation by setting the scene. In Jest, I create a new file for my test case, like opening a fresh page in my detective journal. I name it something catchy, like algorithm.test.js, so it stands out in the cluttered evidence room of my project directory. If Mocha is my tool of choice, I ensure I have a similar setup, maybe even with a cup of coffee by my side, just like the name suggests.

    Now, I step into the shoes of a storyteller, crafting a tale that describes the problem my algorithm is meant to solve. I wrap my story in a describe block, which frames the context of my investigation. Within this narrative, I write an it block—a vivid scene depicting what should happen when my algorithm tackles the problem. It’s here that I specify an expectation, like declaring, “I expect the sum of 2 and 2 to be 4.” This is my hypothesis, the truth I seek to verify.

    Armed with my Jest magnifying glass, I call upon the expect function, peering closely at the algorithm’s output. Or, with Mocha, I might use an assertion library like Chai to express my expectations. Both are my trusty sidekicks, helping me determine if the narrative matches reality. If the algorithm performs as anticipated, it’s like hearing applause from the audience of code reviewers. If not, well—it’s back to the drawing board, refining the plot until the mystery is solved.


    In Jest, I begin by setting up my test environment. I include the function I want to test, either by importing it from another file or defining it within my test file. Here’s how I might write my test:

    // algorithm.js
    function add(a, b) {
      return a + b;
    }
    
    module.exports = add;
    // algorithm.test.js
    const add = require('./algorithm');
    
    describe('add function', () => {
      it('should return the sum of two numbers', () => {
        expect(add(2, 2)).toBe(4);
        expect(add(-1, 1)).toBe(0);
        expect(add(0, 0)).toBe(0);
      });
    });

    In this code, I use Jest’s describe block to set the context, much like framing the narrative of my investigation. Inside, the it block describes the expected outcome: that the add function should correctly sum two numbers. I use expect to declare my expectations, like a detective verifying a suspect’s alibi.

    If I were using Mocha, the setup would be slightly different, but the essence remains the same. I might use Chai for assertions:

    // algorithm.js
    function add(a, b) {
      return a + b;
    }
    
    module.exports = add;
    // algorithm.test.js
    const { expect } = require('chai');
    const add = require('./algorithm');
    
    describe('add function', () => {
      it('should return the sum of two numbers', () => {
        expect(add(2, 2)).to.equal(4);
        expect(add(-1, 1)).to.equal(0);
        expect(add(0, 0)).to.equal(0);
      });
    });

    Here, Mocha’s describe and it perform a similar role, while Chai’s expect helps me make assertions about add’s behavior.

    Key Takeaways:

    1. Testing Frameworks: Jest and Mocha are powerful tools to ensure your code behaves as expected. Jest integrates smoothly with JavaScript projects, while Mocha allows for flexible configurations with various assertion libraries like Chai.
    2. Describe and It Blocks: These are fundamental in structuring your tests, allowing you to separate different parts of your investigation clearly.
    3. Assertions: Use assertions to express the conditions that must be true for your code to be considered correct. They are like checkpoints in your detective story, ensuring every step is logical and accurate.
    4. Iteration and Improvement: Writing tests is an iterative process. As you refine your algorithm, your tests will evolve, serving as a reliable companion in your coding journey.
  • How Do Jest Matchers toBe and toEqual Differ?

    Hey there, if you enjoy this little tale about JavaScript testing, feel free to give it a like or share it with someone who loves coding stories!


    I’m in a park, the sun shining bright, and there’s a group of us playing with a frisbee. Now, catching a frisbee mid-air is quite the art—it’s all about precision and timing. In the world of JavaScript testing with Jest, matchers are like my skills for catching that frisbee. They help me decide if the catch is perfect or if I need to adjust my technique.

    As we’re playing, my friend throws the frisbee towards me. I leap into the air, reaching out with my hand. This moment, right here, is where toBe comes into play. It’s like that instant when I want to catch the frisbee exactly as it is, without any alterations. If I’m expecting a red frisbee, I want to catch only a red frisbee—no other color will do. toBe checks for that exact match, just like my hand is calibrated to catch that specific frisbee.

    Now, imagine another scenario. This time, my friend throws a frisbee that’s the same shape and size but painted with different patterns. Even though it looks different, the essence of the frisbee remains unchanged. That’s where toEqual comes into play. It’s like I’m focusing on the core attributes of the frisbee—the shape and size—rather than the paint job. toEqual allows me to recognize that even if the frisbee has changed slightly in appearance, it’s fundamentally the same.

    So, there I am, leaping and diving, using my toBe and toEqual skills to make sure I catch the frisbee just right. Matchers in Jest are my trusty guides, helping me determine whether each catch is a success or if I need a little more practice. And as the game goes on, I become more adept at distinguishing between the exact matches and the ones that are equal in essence. Just like in JavaScript testing, it’s all about knowing what to expect and being ready for it.


    First, I imagine the toBe matcher, just like catching the exact red frisbee mid-air. I write a simple test to ensure two variables are exactly the same:

    test('checks if two numbers are exactly the same', () => {
      const speedOfFrisbee = 30; // in mph
      expect(speedOfFrisbee).toBe(30);
    });

    In this test, toBe is like catching that specific red frisbee. The speedOfFrisbee variable must be exactly 30, just like my hand reaching for that exact match.

    Next, I think about the toEqual matcher, where the frisbee’s core attributes matter more than its color. I write another test, this time using objects to illustrate the concept:

    test('checks if two objects are structurally equivalent', () => {
      const frisbee1 = { diameter: 10, weight: 1.2 };
      const frisbee2 = { diameter: 10, weight: 1.2 };
    
      expect(frisbee1).toEqual(frisbee2);
    });

    Here, toEqual is my deep understanding of the frisbee’s essence. Even though frisbee1 and frisbee2 might have different colors or labels in a real-world scenario, their core properties—the diameter and weight—are what matter, just like the shape and size of a frisbee in my hands.

    As I wrap up my coding session, I jot down some key takeaways:

    1. Precision with toBe: Use toBe for primitive values like numbers and strings, where exactness is crucial. It’s like catching the frisbee that matches perfectly.
    2. Structural Comparison with toEqual: Use toEqual for complex structures like objects and arrays, focusing on their core attributes rather than surface differences. It’s about recognizing the essence of the frisbee.
    3. Choosing the Right Matcher: Just like selecting the right technique to catch a frisbee, choosing between toBe and toEqual depends on what I’m testing—exact matches or structural equivalence.
  • How Do Test Cases in Jest/Mocha Solve Code Problems?

    Hey there! If you find this story helpful or entertaining, feel free to like or share it with your buddies who are into coding!


    I’m tackling a complex math problem. The problem is daunting at first, like a towering mountain of numbers and variables. But I’ve got a strategy—breaking it down into smaller, manageable steps. Each step is a tiny victory, a little puzzle piece that fits into the bigger picture. In the world of JavaScript testing with tools like Jest or Mocha, this process is akin to writing test cases.

    Picture this: I’m sitting at my desk, armed with a pencil, eraser, and a blank sheet of paper. My goal is to solve for X, but instead of getting overwhelmed, I take a deep breath and start with the first step—simplifying the equation. In Jest or Mocha, this initial step is like setting up my first test case. I’m defining what I expect from a specific function or piece of code, just like determining the first operation I need to perform in my math problem.

    As I proceed, I jot down each step, checking my work diligently. Each step is crucial; if I skip one, I might not get to the correct solution. In Jest or Mocha, each test case is a step towards ensuring my code behaves as it should. It’s like testing if dividing by a certain number actually simplifies the equation—if it doesn’t work, I know there’s a mistake to fix.

    I continue solving, step by step, feeling a sense of satisfaction with each correct move. Similarly, running my test cases in Jest or Mocha gives me that same thrill. Each passing test confirms that my code is on track, just like each solved step in my math problem brings me closer to the solution.

    Finally, I reach the end, where everything comes together. The solution to the math problem is clear, much like my code, which I now know works perfectly thanks to those carefully crafted test cases. Each test case was a step on a journey to clarity and correctness.


    Let’s say I’m working with a simple function that adds two numbers:

    function add(a, b) {
      return a + b;
    }

    In Jest, I start by writing my first test case, similar to my first step in solving the math problem. This test case checks if adding two positive numbers works as expected:

    test('adds two positive numbers', () => {
      expect(add(2, 3)).toBe(5);
    });

    This is like verifying my initial operation in math. If this test passes, I gain confidence, just like verifying that my first math step was correct.

    Next, I write another test case to check if the function handles negative numbers:

    test('adds a positive and a negative number', () => {
      expect(add(5, -2)).toBe(3);
    });

    This is akin to adding another step in my math problem. It ensures that my function can handle different scenarios, just like checking my math work in different parts of the equation.

    To be thorough, I also add a test case for zero:

    test('adds zero to a number', () => {
      expect(add(0, 5)).toBe(5);
    });

    With each test case, I’m covering different possibilities, much like solving various parts of a complex math problem. Each test is a step towards ensuring my function’s correctness.

    If I were using Mocha, my approach would be similar, but the syntax would look like this:

    const assert = require('assert');
    
    describe('add function', () => {
      it('should add two positive numbers', () => {
        assert.strictEqual(add(2, 3), 5);
      });
    
      it('should add a positive and a negative number', () => {
        assert.strictEqual(add(5, -2), 3);
      });
    
      it('should add zero to a number', () => {
        assert.strictEqual(add(0, 5), 5);
      });
    });

    Key Takeaways:

    1. Break It Down: Just like solving a math problem step-by-step, test cases in Jest or Mocha break down your code into smaller, testable parts.
    2. Thorough Testing: Each test case covers different scenarios, ensuring your code works correctly in all situations, much like verifying each step in math.
    3. Confidence in Code: Running and passing all test cases gives you confidence that your code is reliable, similar to the satisfaction of solving a math problem correctly.