Check out a free preview of the full Testing Fundamentals course
The "Test Doubles" Lesson is part of the full, Testing Fundamentals course featured in this preview video. Here's what you'd learn in this lesson:
Steve introduces Test Doubles, which includes testing tools like stubs, mocks, and spies. These tools are useful for "faking" data or dynamic areas of an application to control the testing environment.
Transcript from the "Test Doubles" Lesson
[00:00:00]
>> Steve Kinney: We're gonna talk about this thing called Test Doubles, which is the overarching umbrella for mocks, and spies, and stubs. And a bunch of other things where honestly, if I wasn't preparing for a course, I would forget the difference between them. Generally speaking, it's a larger concept where there will be no quiz on the vocabulary afterwards, right?
[00:00:20]
Because generally speaking, other than their appearance and the method names, they're all variations in the same concept. If you tell any of the people who center their whole personality around testing that I send any of this, I'll deny it despite the fact that the video exists. But generally speaking, the terminology is not that important, all right, as long as you conceptually get it.
[00:00:46]
So the general idea is like, you're just supposed to test stuff in isolation. Yeah, you know what, turns out our apps tend to call APIs. All right, they tend to sometimes involve time. Right, sometimes they involve console log, or fetch, or something along those lines. Or sometimes they involve a third party library.
[00:01:10]
Honestly, I don't need to test other people's code. What I need to do is make sure, again, the whole thing is if I change my code, does it still work, right? So sometimes we can't control everything, and sometimes you wanna see, okay, this was supposed to call alert, fetch, whatever, right?
[00:01:29]
All right, did the thing get called with the thing it was supposed to get called with is maybe the end result of what you're looking for, right? Yes, it would be great if all code was what they say, idempotent, which is, thing comes in, return value comes out, no side effects whatsoever.
[00:01:48]
But modifying the DOM is a side effect, constant log into the side effect, everything important is a side effect, right? So that's not really the reality we live in, so sometimes we have to kind of worry about the outside world. As somebody said earlier in this course, if you get carried away with all this stuff, you will just make a bunch of worthless tests, congratulations.
[00:02:12]
Or we saw before, we can have random values from an ID generator or rolling the dice, so on and so forth, right? Sometimes we just wanna hold a few things steady, right? Again, all of these superpowers I'm about to show you should, with great power comes great responsibility.
[00:02:28]
Do not get carried away, and I'm happy to answer a thousand questions on where those lines are. I will warn you, most of the answers will be unsatisfying. Because it's like, if you would like to hear me say, it depends a lot, I will happily do that. Or if you think about, it's a game of trade-offs, If you could get a perfectly pristine version of your back end quickly in place for one test and then reset it back to its pristine state for the next test.
[00:02:58]
And that that wasn't a pain in the butt, to wire into your test week, yeah, do that, go it, right, that sounds great. Tell me how you did it, right? Or maybe you do need to simulate the network requests, right? Cuz also, that also involves you controlling the entire server too.
[00:03:18]
Because let me tell you how many times both, from incidents or also my test break in staging, because the back end team broke an API in staging, right, now my tests are failing. And so, yes, obviously there's a value in that realism. But also, if my tests are now failing cuz I made a CSS change because something else happened in staging, that's not great either.
[00:03:41]
So there's a time and a place for all these things. Or you wanna run the test without having to spin up the server, cuz again, spinning up a server and taking it down for the test is also extra things that can go wrong. Or time, and there I make the same joke again.
[00:03:58]
So basically, a test double is the broad umbrella for any kinda simulated, fake thing that you are using in your tests, right? And like I said, the differences are not particularly important, but these are the names that they tend to go by. A mock is, again, faking an external thing.
[00:04:21]
A spy is the ability to, kind of watch over a function and see what it got called with, and all those things, right? In case, maybe your function isn't returning something, but it's calling a built-in or library function. And you just wanna make sure that, did it do the thing it was supposed to do cuz I don't have a return value to see here?
[00:04:41]
And again, if you're thinking, couldn't I just pass in values like that dependency injection thing Steve was talking about? That is the right answer, put it in your head right now. This is like, use it when you need it, but be very careful whether or not you need it.
[00:04:57]
Then the other important part is, there are a bunch of ways to put things back after the test, and I'm gonna tell you right now, just to worry about the last one, right? So let's say you decide you are going to mock out fetch, right? Restore would put the original fetch back in place, right?
[00:05:21]
You can always mock it out again. Reset will just keep that existing mock, but then put it back to its place or clear, keep track of everything was recording. But you know what restore will do, the other two as well, right? And so, if you don't know which one to use, yeah, could I lecture you for another 30 minutes on the difference between them?
[00:05:44]
I absolutely could. If you don't know which one to use, just use restore, wait till you have a reason for the other two, right? And I will answer a million questions about them if we have them, but before I lecture you on things, let's just, most of the time restore will get done what you wanted it to do.
[00:06:01]
And you can call that on a given function, or more importantly, again, I'm giving the answers right now, you can just call it on all of them. So what I will tend to do a lot of times is, if I do need to fake some stuff, that's where you can do it before each test, right?
[00:06:19]
Do yourself, put everything back the way it was afterwards. Why do all these exist then? Well, friends, before we had modern test runners, all your tests ran in the same process. And one test could mock out a bunch of stuff, forget to clean up after itself, and then later tests would then use those polluted versions of everything.
[00:06:48]
These days, most modern tests are now, if you know that you were running old, old stuff at work or whatever, then the stuff is more important to you. But V test and JS predominantly have test isolation, which is, each one of those tests runs in an isolated environment.
[00:07:07]
The risk of spillover is a lot less, right? But like, again, under the hood, so there was this years and years ago, I'm talking a decade. Yeah, there was this mocking and stubbing library called Sinon, S-I-N-O-N. You know what V test uses under the hood? Sinon, same stuff.
[00:07:28]
It's like none of this stuff has actually changed, right? And so if you see Sinon on your code base, guess what? All of this stuff applies, because this is just a wrapper around literally that library, right? I think there will be occasional times where if we hover over stuff in TeleSense, you'll see it peek out.
[00:07:47]
So the good news is, yeah, a lot of the stuff doesn't matter because that expect stuff we've seen that's Chai, which is again, a over a decade-old assertion library, Sinon as a decade old mocking library. Say, JS and V test, just wrap over them, right? I think JS wraps over Jasmine, which is a 15-year-old test runner.
[00:08:07]
So that's why when I say this stuff, the differences don't really matter cuz a lot of times they are very similar in the way that they approach things.
Learn Straight from the Experts Who Shape the Modern Web
- In-depth Courses
- Industry Leading Experts
- Learning Paths
- Live Interactive Workshops