Press "Enter" to skip to content

Unit testing in JavaScript Part 4 – Mocking basics


Monday morning in the last episode we

factored our vanilla JavaScript test

suite to use the test runner Jes instead

in this video we are going to make some

addition to our actual code the tested

code and add some code that a

synchronously fetches data from a web

service and in order to do that we are

going to mock that call which means that

today’s episode is about mocking I and

mpj and you are watching fun fun

function

alright so if you’re a regular viewer

you might notice that I’m in a new space

this is my new studio space that is

dedicated for just fun fun function

there’s no I have not done any sound or

anything of this space yet I just

arrived yesterday and that’s why there’s

so much echo that’s gonna be fixed in in

the coming videos and also not too

exciting might have to do something

about that as well and also I’m not sure

about the angle or anything really it’s

gonna be exciting I’m gonna make this a

bit more cozy and then would probably do

a full studio tour of this space I’m

super excited about it it feels really

good to have like a probable work place

to go to and yeah it’s gonna be great

anyway today we are going to explore MOC

functions

MOC functions are fake functions that we

use in place of doing a real network or

database call or perhaps not do a call

to a payment API in our tests we do this

because we need to run unit tests and

other automated tests in general

hundreds and hundreds and hundreds of

times and we need to run them very fast

so in some cases it’s just impossible to

use a real payment err real API for

instance in like we can do 200 tests

credit card transactions and even if

they provide us with a test API we were

like it would be very very slow to keep

doing real Network calls all the time

because if you’ve run a unit testing

suite it usually has like four to seven

hundred tests and you want to be able to

run those and in minutes or preferably

seconds and that if you just involved

involve the network calls and that yes

becomes totally unfeasible also Network

calls tends to fail

some other time which means that your

test suite ends up being brittle and

like you run 400 thousands

one has felt there and you run for an

chest and one test fails there and it’s

just yeah mock functions return fake

values and mock functions also allow us

to inspect the mock function after we’ve

completed running the test so that we

can check that the mock function was

called in the way that we expected it to

be so let’s have a look at a problem

that we need Marx to solve all right

here we have our old friend from the

last episodes our order total function

let me add a line break here yeah

because that’s nicer when dealing with

e-commerce systems we need to deal with

tax right and in Europe we have this

thing called value-added tax which is

kind of similar similar to sales tax in

the US and the complexity of this is

that when you sell to a person in

another EU country you need to charge

them the sale tax that’s the vit the

value-added tax that is applicable in

their country so if you are selling to

Germany you need to charge 19 percent

tax and register that and you need to if

you sell to somebody in the UK you need

to sell them sell them at 20 percent vit

until they exit the European Union where

the brexit so these rates they change

around they they are not stable for all

the eternity so yes we can’t just hard

code them and hope that they never

change thankfully there are some

services that handle this for us such as

the service that we’re going to use

today which is that API dot-com the very

first thing that I would like to do

before doing any kind of coding has to

get a little bit acquainted with this

API I always like to do this the very

first thing when I get exposed to new

API so what we’re going to do is to call

the VAT API completely isolated from all

our other code and or

total and all those concerns and check

it out separately I will elaborate on

why we do it like that in a little bit

but but for now we are not going to jump

ahead into coding tests or code we’re

going to look at the API okay so let’s

have a look here on that API dot-com and

if we look here and here they listed

like examples of different API calls we

are going to do the use this the country

code lookup and here are some PHP but

what we are interested here in is this

JSON response that we get so it’s gonna

be status you’re gonna get the kind of

code blah blah blah blah and here this

is the value that we are interested in

so from Luxembourg Luxembourg we have

the valid it’s 70% vit so it’s under

there is no there is a rates object

which contains our well it contains a

standard standard object which in turn

contains a value and then it contains a

bunch of other as well

reduced and alt and super super reduced

oh for ebooks they have a lower battery

ebooks very interesting either way this

is the one we’re interested in okay so

let’s create a new file sandbox

storge and I’m going to start I’m using

this thing called Quokka

which is really handy it’s it’s a plugin

to do inline evaluation of JavaScript

and I find it really nice when you’re

playing around with the code and also

doing these videos very nice just

playing around with things so we first

we are going to need fetch this is an

old environment so we we need no defects

otherwise we won’t have access to fetch

and let’s see let’s do coal fetch no

hang on I’m good

put this in a result and salt it’s not

the fine of course and let’s do a fetch

and we need and let’s go back to the

thingy where’d you go so this is the end

point you know let me steal that copy

paste paste that in that’s PHP we don’t

want PHP for now I’m just going to use

de for that Deutschland or Germany so so

far we have some result here let’s see

let’s see what that is because we want

the response dot txt all right cool it’s

status for a-1 authentication required

mmm let’s go back look at the docs

API key and we need some header thing

mm-hmm

API key okay so what we need to do is it

needs temple that location header as

well if I key I think like here they

actually use an uppercase a and I happen

to know that according to the HTTP

standard point or H better yeah it

should be these these are required to be

cases is it fun fact if you’re building

an API either way I have already put

this thing in my environment variables

did to do and I think I put it as in

God there this is this is just so that

you don’t see my API key and but if

you’re doing this yourself you can just

paste your API key here that you

generate on a VAT API does call anyway

does that help us does no we still get

authentication required uh-huh oh wait

I’m not actually I’m just passing this

in as an option if I must actually tell

fish that it’s these this is a header

sorry fetch I keep assuming that you

okay you have reached a limit of API

calls for your blah blah blah blah blah

let me sign into better API to come and

buy more credits because I I’ve done

this a lot of times rehearsing this and

I ran out of credits right I have now

paid more API calls I made so many guy

calls when testing this so we have some

stuff here okay now it’s 200 status

country code ee alright nice

where is hang on its rates that we’re

looking at so let me do forces as JSON

instead it’s Jason and then I’m going to

see that data data dot rates what does

that give us come on

okay and then we have standard here

let’s see data rate standard see what it

gives us okay web an object value 19 and

so we just extract the value and then we

have what we want okay so this is

basically the call that we want our code

to make alright so let me talk a little

bit why we did this white play around

and explore the API separately and

because when I was a younger programmer

I would I would just start writing code

very fast I was a very very goal

oriented and solution oriented and

like I wanted to start writing code

right away so I would just like start

writing fetch right into order total

here but over time I learned that this

cost me too I had meant that I had to

handle multiple problems in my head at

the same time I had to event that I had

to deal with the problem of figuring out

the API and integrating the API into my

existing logic as well and having to

deal with those problems simultaneously

tended to result in me making more

mistakes and moving more slowly overall

and this was especially true if on days

when I was not at the top of my game I

was tired or I was sad from something

that happened in my personal life I

ended up being a like my productivity

ended up being very unreliable it

sometimes work but sometimes I just got

stuck and I produce code very slowly and

and the the code that I produce was also

more error-prone and after I saw this

problem I I did something that improved

me a lot as a program and that was

starting to look for opportunities where

there there’s actually two problems or

more baked into one big problem and

looking for an opportunity perhaps we

can break these problems out into

smaller isolated problems and deal with

them separately and one very concrete

example that is what we’re doing here

would work what we did here is to get a

little bit lovey dovey with an API first

before using it in your code alright so

let’s go back to our tests in the series

we are writing our unit tests first

before we write the code and the reason

why we do that is

that I find at least that it is much

easier to figure out what tests to write

if you write the tests first whenever I

try to write tests after I’ve written

code I tend to struggle a lot to figure

out what tests need to be written

okay so test first we talked we’ve

talked about why it’s a good idea but I

still have a problem with it because

like how do you do how do you think in

tests first because that then it’s

writing the test before the code feels

like backwards thinking to me how do you

get into the how do you make that not

backwards thinking yes yeah exactly I

feel that this writing test first is not

what I am used to and therefore it makes

me uncomfortable it’s a new way for me

to think and I I think I need some

hand-holding

on how to do this that is that those are

excellent points i if you don’t know I’m

like I’m standing on this balance board

it’s like it’s fantastic because it

keeps me thinking clearly but it’s also

sometimes a little bit wobbly anyway the

key is to instead or thinking in terms

of what the computer execute is you

think in terms of examples not what the

computer executors think call examples

so instead of thinking in terms of code

of order total we’re thinking in terms

of examples of how to call order total

and when you think about it that is in

general a pretty good way of describing

how something works a series of examples

if you’ve ever read board game rules

this becomes very obvious reading yes

the rules without any examples it

becomes very hard to parse because of

that it’s very common for good board

game rules to have

series of examples next to each rule set

to explain like specific cases of how

this rule could be applied and sometimes

I even include entire game sessions so

that you can get a sense of how the game

works

code at least to me yes it’s very

similar to that when a function is you

know 10 or 30 lines long perhaps branch

by a few if statements here and there

then I find it hard to understand all

the nuances of it if there are unit

tests for that function showing a couple

of test cases that makes it a lot easier

for me to parse so these tests here you

can think of them as examples showing

how we how order total works or how we

want order total to work when we’re

writing a test that doesn’t have the

code written for it yet so given that

how can we change these tests you to

take a step towards the code that we

want well the first thing that comes to

mind is that as we introduce fetch to

this and a synchronous API call the

order total is now going to become a

synchronous it’s going to return a

promise so I think that is the first

small step that we’re going to do we

can’t avoid that so let’s change all of

all right let’s I know that this will

break our test but nope let’s verify

that NPM test Bam Bam Bam Bam Bam

four failed so let’s go and fix or code

so that this is this this becomes a

synchronous returns a promise promise

promise promise don’t resolve strap this

in puff by the way if you don’t know if

your promises not resolve is new to you

all it does is that it takes a value and

wraps that in a promise and if you’re

not familiar with promises in general

you I made a video on promises here that

you can check out this is also in the

exo description let’s run tests again

and ham tests for past ice cream I know

buddy see how we are working in really

tiny steps we are solving one small

problem at a time and this is very

characteristic of unit testing you you

go red green red green red green red

green red green and for me this is very

nice I really like this this is an

absolutely favorite aspect of unit

testing it provides me with a constant

sense of progression it is a

confirmation that I’m doing things

things are going well and as we build a

test suite it also gives me a sense of

safety that we are making actual

progress without breaking any of our

previous test cases all right so now

let’s finally write a test an example

that describes what it is that we want

the code to be doing if stuff stuff

stuff stops okay hmm

but what is it that we actually want the

code to do well we wanted to do

quite a bit of things when you think

about it we wanted to fetch data from

that API calm and then we wanted to

parse that response and then we wanted

to to extract the the response they did

take that response that parse response

and extract the vast Pacific bath value

from it and then we want that to what

multiply the the toe or the total that

we have calculated previously with that

that VAT on a good day

that feels that there’s no problem at

all perfect caffeine rush you I’ve had a

great great week and I slept a lot but

perhaps I’m also having a bad day that

we’re like this is oh good god where do

I begin

and those days are coding often feels a

bit overwhelming you as tired and that’s

cases I find that it’s really good to

your sleep take a step back and ask

myself what is the smallest possible

step that I can take so perhaps it calls

that API calm if country code specified

so initially the tests we were gonna

just focus on making sure that it

actually calls that happier cone at all

that that’s what we’re gonna do baby

steps

so I’m good to take this and just gonna

grab this or the total here you know

that cool and fine let’s just change

this to drag on waffles there’s a really

pricey perhaps I mean therefore we are

only buying two and I’m going to write

country here like and yes let’s use

Germany again here and and after the

call has been completed we are going to

do

what are we going to do

yeah this is where unit testing is

really tricky to me you like how do we

verify that something that hasn’t that

this is something is happening is

happening inside of order total it’s

inside of it it’s calling another

function fashion how do we how can we

inspect that and how can Blair well

perhaps we don’t have to perhaps we can

just have it actually called the API in

the unit test and then then just inspect

with the results that came out just

let’s just use the real thing no no no

we can’t do that like if if we like the

unit tests are supposed to run really

really fast if we we have we’ll have

hundreds of these and they will run all

over the place and if if we have all

these Network calls in our test suite it

will be very slow and we won’t be able

to run it on every same like we want to

yes you’re touching on one of the big

benefits of mocks if we have mock mocks

in place in our in our tests they will

run me immediately and we’ll be able to

run hundreds of tests in just a couple

of seconds which means that we will be

able to test more and be more confident

in our code also tests will be more

reliable so we won’t run into this where

we just hit save and we just find that

ok some network requests fail here or we

have to run it again and just it yes

it’s gonna be nasty ok but even so how

do we actually get at fetch how do we

how do we mock it ok then perhaps the we

there’s a magic library or two that can

kind of move over I’d require and allows

us to inject it into the runtime no

well some people do like that magic

injecting thing and they use it like

just has a no I know

no I don’t like that either right can we

please use something that is it’s clear

and simple and that we can easily see

how it works okay okay what about this

what if we were the ones putting fetch

in there oh you mean that we pass it in

as an argument to the function here like

like like this yes exactly and then we

can then can do something like a fake

fetch like pass that you know also fake

fake fetch and that is just a function

and it takes a rule and then we can just

create a variable here like it’s fake

fetch cold equals false but then when

fake fetch is cold we set that to Chu as

fake fake fetch cold was true and then

in the after after water total is

executed we can do can expect is fake

fetch cold to be true let’s run that and

TM test that should that means that this

should fail and let’s go into order

total and then do assume that we need to

pass in fetch here what’s and we also

know what if order dot country now I

think that we will if we just do this it

will be okay yeah now I know now this

works the the test we created but all of

these actually fail

so let me fix that just quickly just

gonna like em the function boom like

that there and then I’m going to change

the signature of all of these I’m gonna

get an empty function because they don’t

really care about fetch these tests

because they don’t they don’t use use it

they don’t use it so they don’t have a

country so they don’t do the fetch and

if we run this again boom all of them

succeeds okay blow but a beer to come

but we also want to make sure that it

calls that API at home correctly right

now it just calls idiot right now yes

just like fetch it doesn’t really call

it let’s see let’s go back to the API

call let’s go back and check the or they

are let’s go back to the sandbox here

here we have it

I’m gonna copy that go back to the to

the test and then I’m here but before

setting is fake fetch cold we’re

actually going to you expect here we

don’t expect Earl to be due to do this

you know what let’s actually change this

to another come yeah no okay cool let’s

run this this is also important that you

actually check that your newly written

test code is actually failing so that

you actually make sure that it it

actually test something otherwise it’s

very easy to just o write a test and

then immediately jump ahead into writing

the code and you that way you might just

not actually test what you want

so let’s make sure that this actually

calls the correct and the correct you

are cool

that’s nice here

we talked a little bit before like in

previous episodes about triangulation

versus fake it versus the obvious

implementation and here I’m going to be

content with the obvious implementation

if we did triangulation we would write a

test on one more test here to make sure

that this was not accidentally

duplicated between the tests but in this

in this case I’m just going to write the

the correct implementation which is

order dot country let’s run that test

okay so what just happened here what

we’re doing is that we’re creating this

function here called fake fetch it takes

an arrow and then we add an expectation

here that the L should be right no this

here and then take the country code

that is the same as this one here

everywhere and then it takes this

variable sets this variable here is fake

fetched call to true which we then after

all they set it down we expect is fake

fetch called to be true so we are

testing if country code specified here

but you know we we don’t actually do

that in this test so I’m going to remove

that and I’m going to put that yes here

to remind ourselves that we need to do

that later and this is a way of creating

pending tests I’m not providing a body

so now when I run NPM tests it’s going

to show how one skipped so this is kind

of like can use this as a kind of to do

or in writing our test is very nice I

know a lot of you will probably annoyed

by the fact that I’m I’m not

paying much attention to test naming yet

but we will get to that later

I’m yes at this point it’s that’s not

what we’re looking at and the way this

all works is that we are passing this

this fetch into order total as an

argument so or the total does not

require fetch here we don’t do when a

const

fetch require note fetch we are we’re

not doing that we are getting that as an

argument to this to this function and

this is a technique called dependency

injection it’s very common to use in

unit tested applications because it’s a

very simple way of of providing this and

there’s a lot to this I’ve made a

separate episode about this you’re going

to see a lot of it in this in this

series but if you’re more interested in

like specifically diving into dependency

injection you can check out this episode

here and this is also a episode in link

in the episode description to that

series if you’re interested all that

said I think that this episode is

getting a little bit long here so we’re

going to end it right here like ooh

cliffhanger next week we’re going to

proceed with implementing response

parsing in this in this fetch API and

we’re also going to perhaps we’re gonna

fix this little thing here like that if

country test specified like do a

negative test maybe maybe you start

looking at the specific mock function

mock helpers that are in or ingest

because this is just us creating a mock

mock function here completely manually

would vanilla JavaScript nuts we can do

that you often do that but it’s also

nice to use the the jest helpers to make

things a little bit more terse sometimes

might get to that next time you have

just watched an episode of fun fun

function I release these every Monday

morning Oh 800 G

team if you’re watching from the future

you can check out next week’s episode

here and if you’re watching from present

time you can click here to subscribe so

that you don’t miss that episode if

you’re really forgetful you can also

turn on notifications in I am nvj until next Monday morning stay tuned

Please follow and like us: