Press "Enter" to skip to content

Structuring JavaScript projects for testability


good Monday morning today I would like

to talk to you a little bit about how I

structure my projects for testability

I am mpj and you are watching fun fun

function you might be wondering why is

this pretentious person wearing a scarf

I’m not pretentious well I am

pretentious but it’s because this is

Sweden I live in Sweden and it’s very

cold in Sweden and I’ve gotten a cold

from the cold in Sweden so I’m cold I

have a cold that’s also why my voice I

get a lot of requests for showing more

real world projects on the channel so I

I figured that I would do that we can’t

really show a project from start to

finish because that is like that’s

hundreds of hours of time and I it would

be just very boring what I can do though

is to show you parts of my development

process on the Fun Fun forum Automator

which is a little tool that i have that

automates a bunch of little things for

the Fun Fun forum which you get access

to if you are a patron of fun fun

function if you’re interested in that

you can check out that video talking

about why you should become a patron but

that’s not really that’s not really at

all necessary or even necessary to

understand this video that is just if

you want to support the channel so let

me show you what we are going to work on

today all right so this is the Fun Fun

forum it’s a discourse installation

which is an open-source forum software

it’s really great

and among other capabilities it has

these badges and what I want to do is

create badges for your editor identity

or your vias code person or you an atom

person are you is a blind person or your

vim person

and assign and give you the capability

of warding these badges to yourself

because you are like an amazing vehicle

person and to do this we’re going to use

the discourse API and we have this is

the discourse API we have an endpoint

which allows us to assign a badge to

user

it’s called user badges dot Jason and I

have this thing called the fun fun

Automator on Heroku which is already

doing this doing a bunch of things so

for instance it has this endpoint which

is hackable Jason which is a pretty

funky thing you can you can add

arbitrary Jason to your user profile and

then other users get access to that and

can build dumb apps on top of it it’s

just that it’s just a fun thing from

capability of the forum and I’m telling

you this because this hackable json

endpoint is what we’re going to base

this thing on like this take a look at

this existing code so if you look here

and the in the source map by the way

this code is linked in the episode

description so if you want to follow

along you can just check that specific

branch out

so what we’re interested in here is in

the hackable Jason function so let’s

actually have a look at the you see that

there’s a hackable jason with jhe’s

there’s also a hackable jason dot

sandbox j s and the hackable jason dot

test jeaious we’re gonna check out

hackable sandbox hackable Jason taught

sandbox ojs first gonna open up an

integrated terminal actually and I’m

going to go node dot SRC dot packable

json dot sandbox J’s and that shows us

well

bunch of jason and whoops sorry and

that’s basically the json that we saw on

there

on the endpoint as well and you see here

that hackable Jason let me actually

delete that hackable Jason it just

requires hackable Jason this one and

then it calls it and then logs it up

that’s all it does and that gives us

this thing sandbox is a concept that I

like to use to just play around with the

live function without have to bother

with the rest of the app this is just a

function that returns stuff from the

from the real data thingamabob so little

sandbox he has to test hackable Jason

out and see how it works let’s have a

look in the hackable jason JS file whoa

this was strange this requires in some

query and there’s a require here and

then we call that queer with the what

okay to make us more unconfused let’s

have a look at a query here how does

that work that is another function so

let’s jump into the query sandbox

so okay okay so query accepts a three

and then some parameters and then it

sniffs let’s actually just run the

sandbox and have a look at what what it

does so node SRC query sandbox jazz

alright so this gives us a bunch of

things let me explain to you what the

hell is happening here

so query three so in discourse there’s

this capability of I can create

arbitrary SQL queries on the discourse

database and expose them as API

endpoints with it which is very very

handy when you need to extract large

amounts of data so what you see here is

the query number three that’s actually

that there and see what that that query

is that is the daily active users end

point for the

for the forum so you can see how many

users the forum has at any given time

it’s very handy for doing data analysis

for my moderators or me or you if you

want to see how many people are active

on the forum and super sniff is

basically just a fancy console.log that

I use for debugging stuff like this it’s

a little more than I wrote you can check

it out if you’re interested

otherwise you can just think of it as

doing kind of like the same thing as as

this no move if I change this to one

that is actually going to give us

hackable JSON let me actually just leet

those parameters because Haeckel Jason

doesn’t care about her answers and that

gives us this data so that gives you an

idea what query yes it just gives us

like the SQL ROS basically and then

hackable jason has as its job to mangle

that a bit little bit to remove like the

superfluous data of of that result so

perhaps we can see it here I don’t know

yeah so you see here like it gives a

success true and it gives us rose and we

don’t really care about all that so let

me close the query sandbox and then have

a look again inside of hackable jason

and try to make sense of this

so it takes this requires in a hackable

JSON Factory the kid this this is still

a little bit confusing so let’s just

jump into this Factory and see what is

what is happening inside on that one

okay okay so it has a constant hackable

JSON query ID all right and that that

makes sense it’s it’s the query for it

for this thing like it’s if we go to the

data Explorer it’s the query for the

hackable jason that makes sense then it

declares a function which

depths on this stands for dependencies

and then that function will return

another function which is the actual

function that does the D hackable jason

mad very fishy that actually calls query

CC here like what you need to note here

is that we are doing a dependency

injection we are injecting the

dependencies into the function instead

of you requiring them directly and the

reason we do this is so that we can

intercept it and test it I’m going to

show you that later but what it does it

like it’s called depth to query and then

it just takes that result and then it

extracts the users from from the rows

you see here from the results down here

that this is just the properties that it

extracts doesn’t so far this function

really doesn’t do much at all like like

all good functions it’s very small and

does very little so it’s a factory that

creates the hackable json function it’s

a makes vacuum a liaison functions so

let’s go back to hackable jason is the

we are microphone so you see hairlike

can extract this to make it a bit more

obvious like factory wrap and then we

call the factory with the dependencies

so maybe i can even make this a bit more

obvious by doing this depths and then la

query and then passing in adapts here so

this is the pattern we instead of

allowing the factory itself to require

things on its own we pass it in to

the Pasadena to the factory let me show

you why we do that that is so that we

can write tests for it so let me show

you how a test is structured actually

and I’m gonna close the to you all for

now this is the test so first it

requires in the factory so it doesn’t

care about this file here it it only

tests the factory the factory is where

the actual code is that’s what we’re

testing so here we begin our test suite

so this is just and a test suite is

started by calling describe and then

inside of this test you might have

multiple tests this is this test which

just contains one test so far because

the function is very simple so far and

yes I just call it happy path and that’s

usually what I call my first test

because later usually naming schemes

emerge but for me it’s just like okay

we’re testing the happy part that’s the

first thing we do and you just this is

the before each ingest this is what is

executed every before every test and we

create a fake dependency object fake

depths object which has a fake query

object Porges know for now and then we

create the hackable jason function by

calling the factory with the depths or

fake depths let me actually show you the

the factory side by side so that you can

reason about this thing a little bit

more like sanely there okay okay so and

i need to close that as well alright so

we have when hackable jason is called

here it will call depths not query with

the hackable

Jason query ID but that’s over here and

in order for to test that test that it’s

calling it with the correct ID we are

here assigning depth of query to like

we’re creating this fake function it’s

not a fake function it’s a real function

but it’s fake it’s it’s not the real

depth query function and the first thing

that we do is that we use the experiment

that ID is one let me actually just

start my test runner wallaby which is

great little test runner that I’ve made

it’s a sponsor but I use it anyway you

can check out the video showing it there

if you’re interested so if I change this

to be to this test is going to break

like it expects it to be one then if it

doesn’t explode here it’s going to you

continue and just return a promise that

resolves to like this result that we saw

before X it’s rows with some uses some

stuff and that is what we’re going to

get here so when that is resolved that

is the result that is we’re going to do

see here and then it’s going to map over

this and create these new objects with

username and hack well judge a cabal

Jason properties so I’ve if I changed

this to worse nor a full name and say

that you see that okay it will fail here

because it expected value to be some

username and he received undefined

because I’ve assigned an awful name so

that’s basically how it works we have

this factory function that accepts

dependencies and then returns our actual

proper function and it these

dependencies here we override them here

with a function that expects to be

called in a certain way and if it is

called in the correct way it would will

return some

simulated data that we want to return

and then we can verify that hackable

Jason actually does what we expected to

do with that data here and then we

return that to just and just expect to

get it promised that resolves and that

that is actually all we have time for

today because like I’m trying to keep

these new episodes short and sweet you

probably have like a million objections

comments thoughts confusions around this

code there’s again you can check out the

the code for this for the episode in the

episode description find that find the

source code tomorrow Tuesday I’m going

to be live coding the like the basis for

next week’s episode so if you have any

comments or thoughts or stuff on on what

you saw here today do tuned in to that

live stream you can find me on twitch TV

slash fun fun function that link is also

in the episode description we’re going

to start out with questions and answers

about this code and like well whatever

you want to talk about really and then

I’m going to be live coding and you can

follow along if you like

if you are new then welcome you have

just watched an episode of fun fun

function I release these every Monday

morning Oh 800 GMT if you are forgetful

you can click Subscribe here turn on

notifications in the YouTube app if you

have it or you can just watch another

episode right now by clicking here and

don’t forget to tune in to the live

stream tomorrow I am MP sick mbj until next Monday morning stay curious

Please follow and like us: