Ryan Johnson
Software Engineer @ Olo

JavaScript Unit Testing Part 1

October 3, 2024

I did a series of quick talks at my job at Olo to try to familiarize more of the extended team with some best practices for JavaScript/TypeScript unit testing.

This is my attempt at translating those talks into blog posts. A certain level of JavaScript knowledge is assumed.

I hope you enjoy. 😁


First, let's define testing. For the purposes of these blog posts I'm hoping to definite it fairly simply.

Given a certain input, assert that a function returns a certain output.

Simple enough, right? (something something side effects... 😜)

Now let's get to some actual testing code, shall we?

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

if (add(2, 2) === 4) {
    console.log('Correct!');
} else {
    console.log('Wrong!');
}

Wait a second-- this is a test? Yes actually. This is a test without a test framework and in its most simple form. We have a way of asserting a result (===) and some output for the developer to see if they wrote their function correctly (console.log).

Let's clean this up a bit!

const actual = add(2, 2);
const expected = 4;
if (actual === expected) {
    console.log('✅ Correct!');
} else {
    console.log(`❌ Wrong! Expected ${expected} but got ${actual}`);
}

But this still just looks like an if statement, right? How can this be testing?

What if we were to refactor this like so?

function test(name: string, fn: () => void) {
    console.log(name);
    fn();
}

function expectEqual(actual: unknown, expected: unknown) {
    if (actual === expected) {
        console.log(' ✅ Correct!');
    } else {
        console.log(` ❌ Wrong! Expected ${expected} but got ${actual}`);
    }
}

test('2 + 2 = 4', () => {
    expectEqual(add(2, 2), 4);
});

test('3 + 5 = 9', () => {
    expectEqual(add(3, 5), 9);
});

And if we run this code:

2 + 2 = 4
 ✅ Correct!
3 + 5 = 9
 ❌ Wrong! Expected 9 but got 8

This is probably more what you'd expect testing to look like, right?

All of this is to hopefully illustrate that test frameworks like Vitest or Jest aren't magic. They're just JavaScript / TypeScript code just like you write every day. 😃

Next time I'm going to dive into actually using Vitest and showing the very basics of it. Thank you for reading!

SASS Variables and @use

January 28, 2024

It's been a minute since I've used SASS variables extensively. So of course when looking to add some for viewport widths and thickness for my site, I had to look back up the docs on how to do them exactly.

I immediately went to search on the docs for the @import syntax when the search result of "What's Wrong with @import?" came up. Wait-- am I not supposed to use @import? 😳

Turns out, no. From the SASS docs:

The Sass team discourages the continued use of the @import rule. Sass will gradually phase it out over the next few years, and eventually remove it from the language entirely. Prefer the @use rule instead.

So what's this @use rule? 🤔 Turns out, it's just like import, but uses modules instead. 🎉

So, instead of all the variables being "globally" scoped whenever you import a file, they are namespaced like a module. For example, I created a styles/viewports.scss file with the following contents:

$small: 430px;

Then, in my page.module.scss file, I can import, I mean use, the viewports.scss file like this:

@use '@/styles/viewports.scss';

And now I've got my viewports that I can reference for media queries like this:

@media (min-width: viewports.$small)  {
	...
}

I did the same thing with a styles/thickness.scss file, so I can then do:

@use '@/styles/thickness.scss';
...
margin: thickness.$medium;

This feels so much better than having to worry about variable collisions with multiple imports, and also lets you name things more simply inside the variable files themselves (e.g. $small instead of $smallViewport).

Getting Back to it

January 27, 2024

Restarting the ol' site. I'm hoping to post some simple example code and just practice my writing.