Check out a free preview of the full Testing Fundamentals course
The "Mocking Time" Lesson is part of the full, Testing Fundamentals course featured in this preview video. Here's what you'd learn in this lesson:
Steve demonstrates the methods provided by Vitest for mocking dates and times. These methods are useful for testing how UI elements behave in time-based situations like showing the time since a specific update or an interaction that need to occur after a specific time.
Transcript from the "Mocking Time" Lesson
[00:00:00]
>> Steve Kinney: This is tricky. Yeah, this is a dumb version. This is like, take a call back, but do it one second later, right? Where this is more useful is show an alert and then hide it after a certain amount of time, right? And any of those things where it's like, show the banner, hide the banner, so on and so forth, right?
[00:00:25]
You have a few options, you could say that, okay, well, the banner's supposed to be there for three seconds. What if it's supposed to be there for ten seconds, right? Were you gonna have your test suite wait for ten seconds? How many times are you gonna do that?
[00:00:38]
Not that often before you have a ten minute, test suite, right? What we want to do is instead, and this is also useful if you have something you're trying to date format, or you ever see those posted two hours and three minutes ago. How are you gonna write that test?
[00:01:01]
Time keeps moving, right? The idea is, one thing you can also do in your mock environment is set the current time and leave the time frozen for a second, right? And then advance the time, you can just move the clock. So if this thing is supposed to be there.
[00:01:22]
So this one for instance, we're gonna pass it a function, it gets called in a second. So we don't wanna have the test suite wait for a second. So what we do is, we stop the clock to whatever time we want, in this case, it doesn't really matter.
[00:01:37]
But if you had something where you wanna do durations or something like that, it's useful to stop the clock, and then see with time frozen. We can stop the clock, then caller function, move the clock up one second and verify that it was called, right? And that's, again, that kinda stuff I don't mind mocking, right?
[00:02:01]
Cuz I'm not taking entire modules and trying to think I'm better than them and figure it all out. What I'm trying to do, basically, is control reality so I can test my code. Makes it sound better when I say it like that, right? Let's say we've got,
>> Steve Kinney: We'll say, I have this up here, let's not do that.
[00:02:26]
>> Steve Kinney: beforeEach,
>> Steve Kinney: And afterEach we'll go ahead and we'll put back time. Which, again, with test isolation, we can argue how important that is, but it makes me feel like I'm a responsible person.
>> Steve Kinney: UseRealTimers, cool. So now what we can do is we can give it a callback, so we'll say,
>> Steve Kinney: vi.fn, and what we'll do is we'll say.
[00:03:43]
Now if we just run this function, as it is now, it's gonna fail.
>> Steve Kinney: I'm not skipping that one anymore, right? Okay, cool.
>> Steve Kinney: Right, cool, what'd you angry about? I didn't pull that in, that's not why you're supposed to fail.
>> Steve Kinney: All right, okay, cool. It was never called, and that's problematic.
[00:04:24]
So, now what we can do here is we can say,
>> Steve Kinney: Let's just say 200 milliseconds and now it's passing, right? And now we don't necessarily need to worry too much about, waiting a second or anything like that. We froze time, we said we have the set interval that's supposed to be 1000 milliseconds later.
[00:04:50]
All we did was we called it and then we forwarded time, and should be like, you should have triggered, right? And the other really interesting one that you can do is for even more fun, you can do.
>> Steve Kinney: Which is when we fired this setTimeout, it registered a timer with the JavaScript engine, in this case, node.
[00:05:24]
So this one is just like, I don't know when the next timer was, but just fast forward time until the next timer goes off, right? Which is that set timeout. And so you could do a thousand milliseconds, you can just be, forward time until like that setTimeout is called, right?
[00:05:40]
And which point you can go ahead and get a sense, right? And so we can even say,
>> Steve Kinney: I don't know what the full date is gonna be. Yeah, so it's midnight UTC and whatever. And so time is basically, at this point, you can see it's 1 second after midnight because it had to advance to the NextTimer, right?
[00:06:14]
But time is effectively frozen still. And so if I needed to do time since components, right, posted two hours three minutes ago, it's nice if you can hold time in place, right? And so you can basically say, set the clock to this pass in a bunch of inputs.
[00:06:31]
Okay, I'm gonna advance the time two hours, and now it should say two hours ago, right? I can advance the time three hours, it should now say three hours ago, right? And you can kind of, those things I think are fair to fake, cuz you're just trying to hold something down.
[00:06:45]
Still so you can test it, right? Can you mock out entire modules. Yes. Right, but think about the number of things in a fetch request. Like a get fine. But then you got to actually have the response.json, so on and so forth. It can get really kinda tricky.
[00:07:05]
If you pull out the data fetching to their own functions, they become easier, right? If you're doing everything in one giant component, yeah, it's gonna be hard to test. That's not a testing problem, that's a your code problem, right? And you can solve that problem by kinda pulling the pieces out and then passing them back in, and so now that the thing that goes and hits the API.
[00:07:25]
You can test that separately, and the component can know nothing about hitting the API, right? It's just gonna get a function that it knows to call. And so now the component, you just say, hey, if I pass you a data fetching component, are you gonna call it the way you should?
[00:07:39]
Great, hey, data fetching component. In this point, I wanna make sure that you are maybe that hitting Axios the right way, right, or so on and so forth. Maybe I'll pass you in something that you can default to.
Learn Straight from the Experts Who Shape the Modern Web
- In-depth Courses
- Industry Leading Experts
- Learning Paths
- Live Interactive Workshops