Heads up! To view this whole video, sign in with your Courses account or enroll in your free 7-day trial. Sign In Enroll
Well done!
You have completed JavaScript Unit Testing!
You have completed JavaScript Unit Testing!
Preview
We might need some assertions other than equal. Letโs expand our test suite to be more descriptive and versatile.
Resources
Video review
- Chai's
.empty
method checks for empty objects, arrays, or strings -
.empty
makes it easy to write expectations without worrying about how the real code will work - You call arrays that look the same โdeeply equalโ, because their โdeepโ internal values are equal
- The
.deep
method allows you to make deep equality comparisons
Related Discussions
Have questions about this video? Start a discussion with the community and Treehouse staff.
Sign upRelated Discussions
Have questions about this video? Start a discussion with the community and Treehouse staff.
Sign up
We're starting to get
the hang of Mocha and BDD and
0:00
we're using it to write
more interesting functions.
0:03
So let's expand our test suite and see
some other things Chai and Mocha can do.
0:05
Now that we can check for a ship,
we also need to register damage on a ship.
0:11
Currently, check for
0:15
ship only reports true or false
depending where ships are located, but
0:16
we need to actually keep track of
the damage each ship has sustained, too.
0:21
So let's start a new test suite to
describe the damage ship function.
0:25
We introduce a test suite and
mocha using describe.
0:29
So right below the check for
ship suite we'll add describe.
0:33
Then we'll pass two arguments,
0:40
the string, damageShip, and a function.
0:46
Then, we'll import the damageShip function
from the ship methods.js file at the top
0:53
of our suite.
0:57
So what do we definitely know about
the way damageShip should work?
1:15
Well, It should probably take a ship,
and a given coordinate of the ship,
1:20
as arguments.
1:23
And we need to know which ship to damage
and which spot to register damage on.
1:24
So, that sounds like a good
expectation of damage ship.
1:29
So we'll create a test spec that
says it should register damage on
1:32
a given ship at a given location.
1:37
So now that we're dealing
with a given ship,
1:53
this function doesn't need any
information about the player object.
1:56
So I'll set up the simplest ship
I need to conduct the test.
2:00
I'll add one ship, one location.
2:05
Then I'll add a damage array to keep
track of the damage that's taken.
2:16
So now I'm going to write
the minimum function I need
2:22
to get the test to run correctly.
2:25
So damaged ship is
different than check for
2:27
ship in that it doesn't return anything.
2:30
So we can't just plug it
into our expect method.
2:33
Instead we have to test the side effects
of damage ship after we call it.
2:36
So inside our spec, if we call,
2:41
damageShip, then past ship and
2:46
the coordinate zero, zero,
what should we expect to be different?
2:51
Well, we should expect the ship's
damage array to be different,
2:58
it should not be empty.
3:01
Remember earlier when we wrote our title
case function, I mentioned that Chai has
3:03
a lot of assertion methods for
making our test easy to write.
3:08
So let's go to the documentation and
see what's available for us to use.
3:11
I've linked to the BDD API docs in
the teacher's notes of this video.
3:15
So, looking through the available methods,
the very first one I see is not.
3:19
And the docs even give me an example.
3:25
So here it says expect
foo to not equal bar.
3:27
Well, that seems useful.
3:31
I've already described my
expectation to myself so
3:33
the damage array should not be empty.
3:36
So I'll just search the page for
empty and see what I get.
3:39
Great, it looks like Chai has
a built in method that checks for
3:45
empty objects, arrays, or strings.
3:49
Cool.
3:51
So this will make it really
easy to write our expectation
3:52
without worrying about how
the real code will work.
3:55
So back inside our spec,
right after damageShip, I'll add
3:59
expect (ship.damage).to.not.be.empty.
4:04
All right, so now, if we save our file and
4:14
run npm test in the console,
we get a type error.
4:16
It says, damageShip is not a function.
4:21
Well, of course because the damage ship
function is missing so let's create it.
4:24
So back inside shipmethod.js,
I'll define the damageShip function.
4:33
And the function will accept
the parameters, ship and coordinates.
4:44
And we'll need to export the function
at the bottom of our file,
4:53
by typing module.exports.damageShip
= damageShip.
5:02
Remember, without these
module.export statements,
5:10
the test files won't have access
to the functions we wrote.
5:13
And they'll fail when we run the tests.
5:17
Alright, so now let's go over
to the console and run npm test.
5:21
So now the test reports a new error,
5:29
it says assertion error,
expected brackets not to be empty.
5:31
So inside the damaged ship function,
we'll say ship.damage.push.
5:36
Then we'll pass coordinates.
5:44
So let's go to the console and
run the test again.
5:48
And great, now the test passes,
5:54
proving that damaged ship can change
the given ship's damage array.
5:56
So now we should add an expectation that
proves we actually added the right thing
6:04
to the array.
6:09
So let's see if Chai can
help us out with this too.
6:10
So once again, I'll search the docs.
6:13
Now I'm not exactly sure what to call
the method I'm looking for here.
6:15
But I do know that I want to check
whether an array has specific members.
6:19
Unfortunately I can't just expect
the first member to equal zero,
6:23
zero because two unique arrays
are never truly equal in JavaScript
6:27
even when they store the same values.
6:32
Every array is a distinct object, but
JavaScript uses strict identity for
6:34
equals, so two arrays could only be equal
if they were really the very same object.
6:39
Not just two objects with all
the same property values.
6:45
We call arrays that look the same
deeply equal, because their deep
6:49
interval values are equal, even though the
arrays themselves are different objects.
6:53
So I'll try searching the page for
array and see what turns up.
6:58
All right, so the first thing I
see is a method called include
7:03
which looks like it checks for an array
for a given value, this is perfect.
7:06
All right, so back inside ship_test.js,
I'll add a new expectation to my spec
7:11
by simply copying this one and
pasting a new one below.
7:16
And this one will say,
7:20
expect(ship.damage).to.include
7:25
zero,zero.
7:33
So now when i go over to the console and
7:36
run the test again,
I see that the test doesn't pass.
7:39
It says expected [ [0,
0 ] ] to include [ 0, 0 ].
7:45
So I can see that the ships.damage
array includes the array I want, but
7:51
Chai doesn't seem to believe it.
7:55
It must be that include doesn't
7:56
really solve our deep
equality problem from before.
7:59
So let's check the docs again.
8:03
Now the problem seems to be deep equality.
8:05
So I'll try searching the page for
deep and see what comes up.
8:08
Great, so this method here
looks good because it allows
8:14
us to make deep equality comparisons,
which is exactly what we need.
8:18
So now I can write an expectation about
the first member of the damage array,
8:24
by changing this expectation here
at the bottom to expect ship.damage
8:28
zero to.deep.equal zero, zero.
8:34
So I'll say to.deep.equal.
8:38
So, basically,
8:42
just check that the first element of
the damage array looks like this.
8:43
All right so now if we save this file and
run npm test in the console.
8:48
Great, it looks like
everything is passing.
8:56
Now we could complicate
the damage ship function by first
8:59
making sure that the ship hasn't already
taken damage at the given location,
9:02
by making sure the location is valid and
so on, but this will do for now.
9:06
Now we need a method that players
can call during the game in order to
9:11
fire on their opponent.
9:15
It should use check for ship to
confirm the attacking player's guess.
9:16
And it should use damage ship to
register damage on their opponent.
9:21
Try and write a test suite for
9:25
this fire function using some of
the assertion methods you learned.
9:27
Like equal, not.equal,
deep.equal, .include and so on.
9:30
You might even check the documentation
to find something more useful for
9:35
your test spec idea.
9:39
The link to that documentation is in
the teacher's notes of this video.
9:40
And if you're feeling confident you
can even try implementing the function
9:44
based on your test suite.
9:48
We've already been using BDD this
whole time, I think you can do it.
9:50
And when you're done, I'll show
you my approach in the next video.
9:54
You need to sign up for Treehouse in order to download course files.
Sign upYou need to sign up for Treehouse in order to set up Workspace
Sign up