JavaScript Testing Practices and Principles

Monkey Path a Mock Solution

Kent C. Dodds

Kent C. Dodds

Professional Trainer
JavaScript Testing Practices and Principles

Check out a free preview of the full JavaScript Testing Practices and Principles course

The "Monkey Path a Mock Solution" Lesson is part of the full, JavaScript Testing Practices and Principles course featured in this preview video. Here's what you'd learn in this lesson:

Kent codes the solution to the previous exercise by monkey patching a fake implementation of the getWinner function so that a more specific assertion can be made.

Preview
Close

Transcript from the "Monkey Path a Mock Solution" Lesson

[00:00:00]
>> Kent: Let's make our assertion much more assertive I guess? Does that make any sense? Yeah, okay, so this is the monkey-patching solution. We're basically going to take the utils and swap out the getWinner function before we call this thumbwar so that thumbwar is calling R and our version of that function.

[00:00:21]
So import oops, import * as utils from '../utils'. And then here we'll say utils.getWinner = {p1, p2}, and of course, always returns player2 cuz let's be honest in a thumbwar between me and Ken, it's gonna be me every time. I'm actually terrified that we'd actually do a thumbwar here just destroy me.

[00:00:52]
So we'll do Kent C Dodds. Sorry, let's do the winner to be Kent C Dodds. And save that, and our test should be passing. Let's just make sure that things can break. Yeah, so cool. So this is my keypatching. One problem with this that I haven't done yet is now, we've changed this getWinner implementation for all of our tests.

[00:01:20]
And so something that you need to do is keep the original getWinner utility. So let's say originalGetWinner = utiles.getWinner. And then you'll wanna restore that at the end of your test [COUGH] to make sure that any other test that are using this module don't also blow up because they are relying on this actually running or whatever.

[00:01:49]
>> Kent: Cool so what are questions you have about this exercise? Anything, nothing? Okay, cool, does anybody see potential problems with this approach?
>> Kent: So I'll give you a hint. So I've got an eslintrc in here that disables a linting rule called import/namespace. This is the ESLint plugin import.

[00:02:19]
And what this rule actually ensures, if I turn this back on, or I'll do warn.
>> Kent: It ensures that you don't make changes to anything that you import, at least not on the name space. So the reason for that is because it's actually, when ES modules are actually implemented in node and if we're using native modules this would actually not work.

[00:02:49]
It might be a syntax error but cert, at least would be a runtime error. So this monkey patching business of modules is not an optimal solution. So, we'll deal with that in a later exercise. The other thing, the other problem with this is that, let's say that if we call getWinner too many times in this function.

[00:03:15]
Or if we call it the wrong way, then things can really blow up. And so as soon as you mock something, or you create a fake version of something in your test. You're severing any confidence that you have integration between that fake thing and whatever you're testing. Because now, let's say that somewhere down the line.

[00:03:41]
Here I'm gonna get rid of that annoying ESLint thing here. So let's say somewhere down the line, our dependency or somebody whose writing this decides that they wanna have, like maybe put a game or something like that. Some additional options or something, if we're still using our mock then actually our test still passed.

[00:04:03]
But the code is totally busted. And so that's what I mean by mocking something you're severing your ability to be confident about that thing because now you have no way of knowing if you're calling that thing properly. And so there are some things that you can do to overcome this.

[00:04:19]
There's definitely a reason to mock things sometimes. Like sometimes you really can't charge somebody's credit card during your test. I don't have enough money in my account. So sorry we can't run the test today, the CTO maxed out his credit card. Yeah, so that's not reasonable. So we do need to do some sort of mocking at some point.

[00:04:41]
But if there is something we can do to sort of restore that confidence in some way, then that would be a really helpful thing. That's actually called contract testing to test that the integration is working properly. And we're not actually going to get into the contract testing, but we're gonna get somewhere a little bit closer to that with our next exercise.

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