Check out a free preview of the full Enterprise UI Development: Testing & Code Quality course

The "Unit Testing Exercise" Lesson is part of the full, Enterprise UI Development: Testing & Code Quality course featured in this preview video. Here's what you'd learn in this lesson:

Students are instructed to complete the test implementations in the exercise.tests.ts file. Use `npm test` to run the tests.


Transcript from the "Unit Testing Exercise" Lesson

>> We're gonna go into a different example, I said that the other one was the only pun. I guess this is a second intentional pun, which is just kind of just looking at, just kicking the tires on some of this stuff. Because what is a course on JavaScript, unless you talk about referential equality versus value equality.

And in this post, everything's got to be immutable world. We mostly should grok this, but it feels like the responsible thing to do to at least talk about this briefly. And we'll check out great-expectations. Cool, and there are a bunch of various different exercises that we'll play around with in here, but we're gonna look at object tests in this case.

I'm just gonna close some things at this point. As most of us know that we expect these tests to fail, because two objects that roughly look the same but aren't actually the same object are not equal to each other. If you did or you did a triple equal sign between two arrays with the same items in it, they are not equal.

Two objects with the same keys and values are not equal. I should choose a better word that is not just the same thing, because down here, you can see that toEqual does a shallow check, right? So they are shallowly equal, which all is shallow. The quality check does is like iterate through the array, or the first thing in both arrays, the same thing, second thing, so on and so forth, right?

Do they have the same number of things, the same keys and same values, right? Cuz otherwise, writing these tests would be terrible, right? And so one of the things to catch yourself on, particularly if you have a failing test, is did you actually get the thing that you mostly wanted, but it's just not the same memory address?

In RAM, cool, then you want toEqual. And there's a lot of nuances to toEqual, and I bring this up, particularly when it comes to adding tests for legacy code, right? And there's a bunch of tricks that you can do with this that make it way easier, particularly in one of the code.

So I work on the objects that have to do with are gigantic, and I don't have time to create the entire object, particularly in TypeScript, gets all angry. So we'll look at some of those tricks. But roughly speaking, if you're just trying to make sure that the various outputs are the same, you want toEqual instead of to be otherwise, it won't work.

This is like if you've come from a library that uses assert, or the one built into node, I believe there is assert.equal, which will fail, cuz that does the equality check, but then deepEqual will do what toEqual does. That's why we're having this discussion, right? Every test framework is a little bit different, Phil.

>> So is toBe, essentially triple equals and toEqual, essentially double equals?
>> The first part of that sentence is totally true.
>> Okay.
>> The second part is imagine iterating over the array, right? Even double equals two arrays that have the same things will still not be true.

A string of 1 and a number 1 will be true, which is the worst case scenario. It's like if you started to go for each on both arrays, compare the indexes of each one. The only one that I couldn't come up with a clever way to do is if you are creating two functions, you're gonna have to find something else.

Unless someone on the chat wants to come up with a better way to do this one but like also not something comes up in reality too often. But you can see referentially, this is the same function, toBe will pass by stored in a variable, but that's really a fake test.

But generally speaking, we have toEqual, and we'll look at one of the powers of toEqual, which is like there are ways. And we'll see this in a second, I'm just kinda building expectation, unintentional pun. To say, I only care about two properties of this object, whatever that other thing is, as long as it's some kinda string or literally anything, I literally only care about two or three properties.

And make sure that this result, which might have 72 different properties, I only care about a few of these, and you can use toEqual to get a little bit more nuanced. So if you find yourself accessing a bunch of properties and writing 42 different expectations, there might be a better way for you, and we'll talk about that in a second or two.

But let's jump in a little bit. What I want you to do at this point is take a look at exercise, where I've got, there is a list, I think I have it in the notes in the repo of every different expectation. You can also go to the docs here and you can see all of them.

I picked the greatest hits, right? These are the ones that when I did a Cmd+F in my own repo, I had way more than the other ones. So we'll kinda just take them for a spin real quick and make sure that everything works. So what you wanna do is you'll notice we have these annotations here.

Dot it or it.todo, it.skip are basically the same, it's a semantic meaning, right? Skip is like, I don't wanna run this test, right? A thing that I might choose to do when we get to some of the things that might happen later in this workshop is I might have a rule that says, hey, don't ship a .skip to production, or I guess your test suite, don't merge it into main.

Yeah, I think older frameworks are worse about this, accidentally open up a PR with a .only. Your tests pass cuz only one of them was running. And so .todo is more like I will eventually write this test, right? A lot of times, I will write a bunch of .todos if I am feeling extra in the mood to do test-driven development.

I will write all the different things that could possibly happen with .todos, I'll just knock them off one at a time. So in this case, this test suite passes. You know why it passes? Cuz it doesn't fail, right? Because these are all marked as todo, and the lack of failure is technically a passing.

So what I want to inspire you to do is start turning off the .todos and see what happens. As you can see, some of these, you got to actually write the implementation. That's why that expect.hasAssertions is here. Cuz otherwise, you would just take off the .todo and the test would pass victory mode, except you didn't do anything, right?

So you can delete this line once you have a real expectation in there, right? Or we can keep it cuz it's not bothering anyone. But yeah, you wanna start knocking these off and just try to do the implementation real quick, and then we'll talk about it together in a little bit.

Learn Straight from the Experts Who Shape the Modern Web

  • In-depth Courses
  • Industry Leading Experts
  • Learning Paths
  • Live Interactive Workshops
Get Unlimited Access Now