
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