Press "Enter" to skip to content

Unit testing in JavaScript Part 5 – Mocking continued


good Monday morning today we are

continuing our series of unit testing

you can check out the full episode

playlist by clicking there and today we

are continuing with exploring mocking I

am mpj and you are watching fun fun

[Music]

all right so let’s have a look at where

we were last time let me close this

window this is the order total function

that we were working on and we see here

that we have we started a bit with

calling fetch here and well it’s not

doing much we also needed to start doing

some response parsing here so I think

that that’s what we were going to

continue it I’m also going to open up

the sandbox so that we remember what

we’re doing here so this is the way you

do a fetch call you you call fetch with

an L and then you parse the response in

this case we’re parse it that’s Jason

and then we’re going to extract the the

vit rate here okay so we have our fake

fetch here and what we want this to do

is return a the promise that resolves to

two response

so you see here fetch returns a promise

and that promise resolves to this

response object which in turn has a

jason jason method on it that in turn

will that will actually also return a

promise that will resolve to this data

here so you know let’s just do that

actually so fake fetch will return I

promised the deter that resolves to a

response object this is a response

object and that has adjacent but

that in turn resolves to order it it’s a

promise

returns a promise that resolves to oh

sorry I’ve switched little woman sandbox

and I resolve to this thing’s it’s data

rate standard value it let me copy that

so that just help me here resolves to an

object that has rates which in turn has

a standard rate which in turn has a

value which is going to be a 19 perhaps

I made a mistake here promise – promise

I’m drunk let me fix that promise or

resolve is of course what am I I meant

anyway given this then Blaire we should

actually expect this to multiply the

value of this order by 19% let’s update

the test to do that so expect result to

be 20 times 2 times 1 19 let’s run that

create integrated terminal and run npm

tests see what we get

get a I expected to get a failure but we

didn’t hmm that’s peculiar new actually

it is not because they I’m hmm let me

close that I’m gonna show you that

mistake I made going to slightly zoom

out as well so that we can see more so

the way just works is that when it comes

to a synchronous test

it needs to know when the test has ended

so you know you can do that by having

these dumb functions and then call them

when at when the test is done we could

see if that worked actually and p.m.

test yeah that that works but that’s not

the way we want to do it because it can

also instead of using this callback

pattern we can just return this this

promise here it’s a bit more no promises

are nice it’s a nice FBI it’s better

than the dun dun thing so just we’ll

cool so these will throw a throwing

error and that will propagate up the

promise chain which jest will then

handle it’s really sleek but either way

we have a problem here we expected the

value to be something like this but we

actually received 40 because we have no

code for this so let’s see here

the fetch simplement this will return a

promise that resolves to a response and

responds has a method for JSON that we

can call which in turn research returns

a promise that resolves to add some data

and that data will have some rates and

one rate that is the standard rate than

that without value of 19 so let’s go

back can implement that data dot rates

and this is standard rate and it has a

lot C there and then

we will use that that rate and will

actually copy this copy this for now and

multiply that with one and on so do take

that times let’s just do that for a

minute we’ll fix that won’t work but

we’ll fix it later let’s just make some

progress see what that turned out to be

cannot read property then or undefined

where was that

where the tojo line three oh we didn’t

get oh this is the happy path we have a

bunch of tests failing now let’s

actually disable all other tests and

focus on one at the moment because it’s

very nice in programming to solve one

problem at a time so adding it only to

the asset means that it will only run

this test which is often very helpful so

let’s see right now this fails hmm all

right it’s still just returning 40 yeah

it’s because we we’re not actually

returning this this promise here it just

makes this request and then it proceeds

to this line here which is not very

useful so we press read write return

okay cool let’s run it again and see

that helps oh yeah

expected forty seven point 59 but we

received our 760 hmm that’s a bit much

it’s because we are multiplying by 19

when we should actually be cursing this

to be 0.19 so I think that if we divide

this by a hundred

I think that’s correct is that correct

yeah maybe let’s see

run NPM test again no that becomes 7.6

now that’s because we are not

multiplying by zero point 19 so it’s

actually the 1 plus zero point 19 see if

that helps hang on

ah yes cool now we were to green get the

correct value

I keep typing NPM tests here but I just

remember that we actually have defined

an NPM watch as well so sorry MVM run

watch that will alter run every time we

um every time we save all right so

there’s some duplication here don’t

worry we will deal with that eventually

but for now you mM put a pin in it we

will be removing duplication but not

until all tests are green

so let’s actually let me remove it only

to see the other failed tests that are

not failing because then is undefined

mimimi mimimi mimimi mimimi

you know and this is because in the

cases we only really do this we only

really want to do this if we have a

country and the order might not

necessarily have a country at perhaps

the user haven’t selected it yet so we

want to just have an if statement here

and do order a dot country and just wrap

this thing in that you know Wow there we

go and now all those tests or or

succeeding we have one skipped test here

because I actually may

a kind of dummy test here

this is coal like I’m I think of these

as to do to do tests so to speak because

I wanted to remember this case but it

seems like we have actually accidentally

solved this because we had tests

breaking for other reasons so I’m

actually gonna delete that we don’t need

to write that test that is over and sell

us now that we have other tests that

just cover that naturally also I think

that this empty function here we don’t

actually need need that anymore because

it’s just not making use of it so I can

just change the empty function to know

to be honest let’s do that so let’s see

null or the total no the active function

no and no there as well we don’t need

that this bit cleaner I feel a little

bit disoriented here with all this

mocking it feels like I don’t quite know

what is real I’m skeptical are we just

whatever we are we actually testing

anything here or are we just creating

this fake fake implementation and then

just testing the fake implementation are

we actually testing any real logic yes

we are like I understand how it might

feel like we’re doing quite a bit of

faking here doing this elaborate mock or

fetch but what we are concerned about is

to check to test if order total is

causing the side effect that we want the

fetch and that it does the right things

with what that would that side effect

the yields which is which is the data so

what the test is doing is we’re

concerned with testing or the total

right and what or the total does is they

cause as a side effect fetch

so this side effect comes out of order

total so to speak and we were inspecting

that this looks correct that’s what

we’re doing and then we are passing a

response back into order total and then

we are inspect what comes out of order

total after that to see that that is

correct

so like request comes out we inspected

that request mmm looks good looks like

we expect it to be then we pass in a

response and then given that response we

inspect that hey we get to correct that

out of that or like the correct order

total where that multiplied in so order

total is what we’re testing we’re not

actually we’re not testing fetch at all

here I’m skeptical does this actually

work is is this we’ve written a lot of

tests now we didn’t want a code but we

have not actually tried it against the

real API we built it checked it out in

the sandbox kind of but we’ve not

actually check that or the total runs

correctly against the real API I’m

interested in the fact that when you’re

doing TDD with mocks it can only become

kind of sordid TDD before we were coding

like Tilly with pure functions we were

writing a bit and then we implemented it

in the code and we would actually see

the real results because there were no

side effect it was just the pure

function and our tests but when we are

doing TDD against mocks it’s just us

creating a fake reality and then we

check using TDD that our our tests does

the right things in this fake reality

and depending on what happens in the

fake reality that

the test does response to that sorry the

code responds to that in the right way

but it all depends on us having the

having correctly designed the fake

reality which means that when we are

doing any kind of mocking we actually do

have to actually test that we have made

right assumptions in our test by

checking the stuff in the sandbox so

let’s see if we can do that actually I’m

going to do import the order total no or

very total $42 and we require and I’m

gonna close this for a bit I’m gonna

start quokka on this file there we go

and we’re gonna call order const result

we’ve got a call order total and the

first argument and is pass in a fetch

because it needs fetch and we are going

to give it some kind of order yes let’s

steal one from this this test here go

back to sandbox pass in this here see

what happens oh cannot read properly

standard or undefined interesting what

is happening so rates is undefined

that’s actually just been x

console.log x see what happens 401

authentication required please pass a

valid API key had it in your request ah

yeah that’s because we need to actually

so we still have some work to do in our

test let me close this for a while and

have a look so not paste this in god I

just grabbed this here to help us have

it side by side go back to the test

you’re gonna paste this in here while we

work if you you if you have a big screen

unlike me who I was doing a youtube

channel you can just split your editor

side-by-side that’s very handy when

doing unit testing to keep the tests

here at your reference code here but

either way this is going to be passed

here as an option options object when I

call it ops at least and we expect

headers dot no sorry respect ops headers

and we expect that you have an API key

property we expect that to be expect

that to be key one two three so what is

key one two three well here’s the thing

we also because this uses process here

we now have another dependency and we

need to create a fake process as well

and pass that in so functions tend to

have a multiple dependencies and that

has an N which in turn has a bat API key

which in turn has should be key one two

three

so let’s actually pull up the terminal

in toggle terminal and I know run all

tests cannot read property headers or

undefined yeah because

hoped first of all it’s not getting an

oops let’s remove this let’s actually

fix that first

so or the total will now pass in some

options you see what happens

category copy the API key of undefined

yeah sure because it wants a headers

bunk we get a new problem here yeah key

1 2 3 received undefined let’s actually

just API key and then I’m gonna write

the hard code the key here so it’s key 1

2 3 start faking it but we want with we

can’t hard code values like this so

we’re going to proceed well hmm actually

ups passing process here this is the

process object we inject that now this

will break all other tests

so let’s actually disable everything but

this no I’m back and dudududu cannot

read

property country of Oh

undefined hang on what is confusing me

here yeah we actually have to pass in

the fake process otherwise the arguments

order is correct click process cool

cause wait a but appear correctly it’s

green but it that’s because we have a

fake value here I’m gonna use the actual

value from process process and

what was it again I won’t go back to the

test

it’s that API key oops and it is green

cool let’s just change this just make

sure that it breaks correctly yep

awesome we’re gonna remove the only and

then we’re gonna see that all the other

tests fail so that’s because they don’t

have a process object these because

these don’t use the don’t use the fetch

we can just pass null in here as well

they don’t matter

don’t make use of this these test cases

so just gonna do not look and we have

five passed so now it now it actually

uses the the correct way about API key

so what’s sure try this again try this

again cannot read property country of on

define now okay of course we need to

pass in the process in the sandbox as

well all right cool yeah we cannot read

property standard or undefined

let’s see what is happening here let’s

check this again X happening console the

log X see oh my god bad requests what’s

bad about it so it was because I had run

out of credits I I refreshed them again

ha note to self don’t use a throttle API

for tutorials cool so let me remove this

console log

and go back to the sandbox finally it

works awesome all right cool so we wrote

some tasks that completed the whole

response chain and the parsing of the

response and then we also verified that

the our mocks our assumptions about the

fake reality that we created actually

correspond to reality by running our

code in the sandbox and true it seems

like it’s working that calls for

celebration

and by celebration I mean a commit all

this changes in the package of jasa yeah

oh I just indented some code let’s keep

that separate the sandbox also got some

changes let’s actually let’s say git

commit that as well

and script MD we don’t want that that’s

my script notes and I want to remove the

the package of JSON there because it was

just that was just an invitation and we

want to keep those in a separate

committee I don’t like putting you know

spelling fixes and stuff like that

baking them into a committee I want I

fixed risk bombs test yes commit

messages are important but not that

important well they are I think they’re

really important but this is not a

tutorial about good commit messages

hello

let’s let’s still do this fixed

indentation issue I know I’m being

inconsistent but let’s see let’s see

let’s see so this is what we added here

some nice new response parsing we have

some duplication here that we will

eventually eventually fix we looked at

the we created Wisc standard or fake

fetch here by checking that it used the

API key that is also passed through fake

process and it’s also we also check that

it use the rate here from the from the

fake VAT IPI to calculate the output

result this thing here this is actually

now redundant because you know since

we’re checking the output which is

completely dependent on fake fetch

actually being called otherwise it

wouldn’t work this thing is just

completely superfluous so we’re gonna

remove that

no longer needed now and we can also

remove these curly brackets we don’t

need them anymore let’s actually just

make sure that the tests are still

running don’t bypassed so let’s let me

superfluous checks

I feel like this injection here results

in extra code if you were not unit

testing this and requiring this thing

here it would like that would mean that

order total could just have required

this on its own inside of itself it

feels like an injection mechanism adds a

little bit of extra code and extra code

but it makes me feel yes it’s a little

bit extra code but it’s it’s not a lot

it’s it’s pretty nice it’s pretty clear

what is happening here we just requiring

in fact we’re passing it in it’s very

easy to follow how the injection happens

process is here a I mean there are other

ways we could achieve it we could use

some kind of messing around with

Global’s and stuff like that but it

wouldn’t really be easier to follow it

might save us a little bit of code but

it would still it feels like it would be

more brittle I like this because it’s

extremely straightforward what is

happening just does have an ability to

override requires so if we used fetch

inside like it with the require inside

of order total we could use that but we

would still have the problem with with

process which is a global variable so we

would have to like mess around with that

global I one advantage with this is that

it makes all dependencies all dependency

mocking behave in same

way which i think is pretty nice and I

think that’s a good point

to end this episode it’s getting kinda

long if you have any questions

confusions or wanderings or suggestions

on where we should go next just post a

question down below in the comment field

or if you are a patron you can post it

in the funfun forum there’s a link in

the episode description for a topic

dedicated to discussing just this

episode you have just watched an episode

of fun fun function I release these

every Monday morning Oh 800 GMT if you

are watching from the future you can

check out next week’s episode here uh

and if you’re watching from the present

you can click here to subscribe so that

you don’t miss that episode you can also

turn on notifications in the YouTube app

if you’re forgetful

I am mpj until next Monday morning stay curious

Please follow and like us: