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
It is a great idea to verify that exceptions are thrown in your code when you intend them to. They are part of your happy path. Let's go catch some!
FIRST
- Fast. Like super fast, or they won't be run.
- Isolated. Make sure you are only testing what you intend to test.
- Repeatable. Every test run should return the same results. Be careful of time and intermittent failures. Over-specifying expectations are usually a sign of possible breakage.
- Self-verifying. If tests are passing, you should feel safe that things are good to go to production. If they are failing, you should fix them, and trust that something indeed is broken. Trust trust trust.
- Timely. Write tests either before or as you write code. Don't fall behind!
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 really learn
how to right good tests.
0:00
Before diving in how to handle verifying
that exceptions are happening like we want
0:03
them to, let's take a quick look at
another testing mnemonic device.
0:07
The first rule to writing
a good test is this.
0:11
Tests should be fast.
0:15
If they don't run fast, the more likely
it is the developers won't run them.
0:17
Unit tests will run fast because
they should be isolated.
0:22
You should not be relying on other code.
0:26
You should use test doubles to make sure
that you are only running the code that
0:28
you are testing.
0:31
We'll talk more on this in a bit.
0:33
You always wanna make sure
that your test is repeatable.
0:35
You should get the same results
every time you run the test.
0:38
You wanna make sure to avoid
intermittent failures and over specify.
0:42
Your test should be self verifying.
0:47
When your entire test suite passes
you should feel comfortable
0:49
that you can ship your code to production.
0:52
When any test is failing, you should
ensure you fix it because something is for
0:55
sure wrong.
1:00
If you can't trust your test and
1:01
the results,
their usefulness starts to diminish.
1:02
Take time to make sure that you and
1:06
your team can verify that
the system is working.
1:07
Write your tests in a timely manner.
1:10
If you are not using the development
practice of test-driven development,
1:13
you should still make sure that you write
tests when you are developing a feature.
1:16
Tests help document what your
code is expected to do and
1:21
verifies that it is working the way
that you, the developer intended.
1:24
Check the teacher's notes for
more on each of these concepts.
1:29
So we have already experienced how
to handle exceptions in our code.
1:32
We can either throw them or
catch them or use a try catch block.
1:36
Now you might be tempted to add tries and
caches to your test.
1:40
I mean it's Java code, it would work.
1:43
In fact, this is an older way of doing
things, you would try some code and
1:46
expect it to fail and in the cache
you'd assert that it happened.
1:49
It's a lot of boiler plate and
annotations really help expose
1:53
a better way of asserting that
exceptions are happening.
1:56
Let's go use them.
1:59
One more quick thing to talk
about before we get started here.
2:01
Did you notice how the tests are all
stating that they throw exception?
2:03
This is a best practice.
2:09
And what this allows for
is that you don't need to try and
2:10
catch things that throw
specific exceptions.
2:13
Now the logic here is this,
if an exception happens and
2:16
you didn't intend it to,
let the test runner report it.
2:20
It will bubble up and
out of the test method and
2:23
the runner will report the exception.
2:25
So over in AlphaNumericChooser you
see how this locationFromInput throws
2:27
InvalidLocationException.
2:32
Now notice how our test over
2:35
doesn't complain that we
didn't catch the exception and
2:37
that's because it has this throws
exception clause at the end, right?
2:40
So let's remove that temporarily.
2:43
Now it's complaining, right?
2:47
And if I look at
the intention action here,
2:48
it's gonna say add the exception
to the methods signature.
2:51
Now I wanna show you this because
this is a pitfall, right.
2:53
So if you do that.
2:56
It's gonna say the specific exception that
you would want, but we don't want that.
2:58
The best practice is to use
the base exception, right?
3:02
And invalid location extends that.
3:06
So it is still saying
that it will throw that,
3:08
which is why it's allowing it to pass.
3:10
Cool.
3:12
All right, so let's make a new test and
have it actually throw an exception.
3:13
In fact, let's check and
3:17
see that the happy path that throws
the exception works as we intend it to.
3:18
Okay, so what is that though?
3:23
So let's look back here.
3:25
Okay, so if it doesn't have
the right buttons, right, if we put
3:27
the wrong input in there and it doesn't
match, it's gonna throw one of those.
3:32
So let's do that.
3:35
Let's go back to our test and
we'll make a new test here.
3:36
And let's call it
choosingWrongInputIsNotAllowed.
3:41
Okay.
3:50
And then, we don't really care about
the value that's returned, right?
3:51
So we use that chooser object, and
3:55
we'll do location from input,
let's just write wrong in there.
3:57
Just make it kinda clear that,
that's happening.
4:01
And what that's gonna do,
that's gonna throw an exception.
4:02
So in fact, why don't we run it and
see what happens?
4:04
Okay, boom.
So it blew up with a red exclamation.
4:09
Before it was yellow
saying that it was a fail,
4:13
this is saying that there's a big thing.
4:14
So it says it threw this invalid button.
4:15
So it's throwing that message.
4:18
Okay, so the test annotation actually
has a field that we can set,
4:20
named expected, and it takes a class.
4:26
So let's do that.
4:28
So we are gonna say that this test here,
expected.
4:29
And it expects
the InvalidLocationException class.
4:36
Cool, and now if we run it, boom.
4:41
It passes.
4:44
And now if we cuz it to actually not blow
up, it [INAUDIBLE] expected exception.
4:45
Like let's give it an actual good input.
4:51
We'll make it A1 and let's run it.
4:52
And boom.
Now it fails and
4:56
it says that we expected the exception and
valid location.
4:57
Exception.
5:00
Pretty cool, right?
5:01
So let's put that back to wrong.
5:02
So, what do you say we catch the other
happy path exception in that method?
5:06
Remember we saw it in AbstractChooser.
5:11
Let's go back to that real quick.
5:15
In AbstractChooser here,
if you try to create a location that's
5:16
larger than the max rows and the max
columns, it will throw an exception.
5:22
It will throw another
invalid location exception.
5:27
Why don't you pause me and
give it a swing?
5:30
When you finish un-pause me and
I'll show you how I did it.
5:32
Ready?
Go catch that exception.
5:35
Okay.
5:38
So let me show you what I did.
5:39
Command in.
5:45
Test method, and we're gonna say
choosingLargerThanMaxIsNotAllowed.
5:46
Okay, and same sorta thing,
5:56
we're gonna say that it's expected,
6:00
invalid location exception.class.
6:05
And we're gonna choose one
that's way bigger, right?
6:15
So let's say locationFromInput,
6:19
we'll give it a good B, but let's make the
second one on the row big, so like a B52.
6:21
Love shack, baby.
6:26
And blammo.
6:29
Test pass.
6:32
Hm, there was something in the creditor
class that we didn't look at.
6:33
Let's go back over there
to that creditor class.
6:38
There was something in here.
6:40
Oh yeah, there's not enough money.
6:41
It throws a not enough fund exception.
6:45
I see a couple of happy paths there
that we didn't cover in our tests yet.
6:48
Wanna go ahead and take that on?
6:51
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