Effective Error Handling and Console Capture Testing
00:00 So the first thing I'm going to do is I'm going to go to vtest config and I'm going to say restore mocks true. So by default at the end of every test or before the test start, at some point between tests, all of the mocks that were created will be restored. I think this is a great default and so we're going to enable it by default.
00:18 We restart due to config changes and now we are in a solid position. So we can come in here and delete this. We no longer need to do that cleanup, which is nice. That doesn't necessarily mean that you can always solve your cleanup problems this way. There are definitely some situations where you want to use the after each hook, but this
00:36 is one of those situations where it's just like, nope, we're not going to do that. We're just going to say always restore mocks. Okay, so now comes to the more complicated bit. How do we take this stuff and move it into a before each test?
00:51 If I say before each and we bring that in from vtest, then we're going to have a bit of an interesting time of it. So I'm going to move this up, stick that right in there and we've got this console error. How do we get access to that console error? Oh no.
01:08 And there are actually some ways to accomplish this through context stuff and that never really worked out well for me. So this is what I do instead. We're going to say let console error, which is a spy instance with the parameters that are type of console error.
01:27 And we're going to assign that to VI spy on console error and then we'll mock the implementation to do nothing. And then actually, you know what? Right now we're mocking the implementation to do nothing.
01:44 In reality, what would be really good is if like we're doing this everywhere. What if we just make sure that people never call console error unless we're expecting it? Right? That would be a good thing. Like we throw an error when console error is called. Okay. Yeah, that's cool.
02:02 So let's take these arguments and we're going to and those arguments aren't going to be typed. It's not going to like that very much. We can take this exact same thing that we had right there. So parameters at type of console error. There we go.
02:22 That works. And then we can say, oh, you know what? We don't want to prevent the console error from happening, right? Like I do want to see what the console error was. I just want to say, hey, you're not allowed to do this. So here's what we're going to do. We're going to say let original console error equal console dot error.
02:42 So now we have access to that. And in fact, you know, this can be const and it can be inside of our before each. So we have access to the original console error. The reason that we can do this is because we're resetting the mocks anyway. So console error will always be reset to its original implementation. Okay.
02:59 So we have original console errors that will call that original, original, original console error with those arguments. So the console error will still happen here. In fact, let's do this console error. There we go. So we're getting it still happening. That's good.
03:17 But then we're going to say throw a new error that explains a console error was called. Maybe you can explain if that is expected, then use console error, mock implementation, yada, yada, yada. There you go. Something like that. Something that's helpful.
03:37 And so now I can look at this and I can see, oh, console error is called. If that's expected. Oh, sweet. And I can see, oh, there's my standard error. That's awesome. And so now in a test where I'm expecting that to happen, I can add a console error, mock
03:54 implementation to do nothing. And then in the test that I'm not expecting it to happen, then I'm like, oh, I wasn't expecting that. I got to go fix it. So let's go fix it. Boom. Fixed. And now my tests are passing in an amazing way. Oh yeah. This is good. I'm feeling really, really good about the way that we put this together.
04:12 So the first thing we did was we restored mocks by default in the vTest config. That's just a really good idea. And then we moved all of our console error stuff into this before each so that we can use this all over the code base. And we will, in short order.
04:29 So then we have our original console error assigned to the console error. We spy on console error and then we mock the implementation so that we can call the original console error and then throw an error and say, hey, the console error was called. That's not good. And you could do the same thing for console info and console log and all of those other
04:48 ones. We'll just do console error today, but feel free to throw that together for the other ones if you'd like. And then for the test where we actually are expecting to have console error, then we opt into that expectation by saying, hey, mock it to do nothing and we'll handle making some
05:07 assertions on how it was called ourselves. And that is taking care of sharing this console error business.