Heads up! To view this whole video, sign in with your Courses account or enroll in your free 7-day trial. Sign In Enroll
Preview
Start a free Courses trial
to watch this video
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