Bummer! This is just a preview. You need to be signed in with a Basic account to view the entire video.
Start a free Basic trial
to watch this video
The happy path makes sure that code works the way it was intended to work.
-
0:00
[MUSIC]
-
0:04
Now that we know how to test, it's time to start looking at the more difficult
-
0:08
question, and that is what to test.
-
0:11
Remember, this is the part where we developers haven't been replaced yet.
-
0:16
What we've looked at thus far is what is known as the happy path.
-
0:19
You should be able to determine what that path is by asking yourself this question.
-
0:23
If this code ran correctly, how would I know?
-
0:27
I'd like to take a moment to practice a skill once more.
-
0:30
Along with all the other parts we learned in the how to test stage.
-
0:34
Why don't we take a look at the other component that we broke out, the chooser?
-
0:38
Specifically, let's take a look at the alpha numeric chooser.
-
0:42
Okay, so we will press the double shift.
-
0:45
We'll do Shift, Shift and then I'll start looking for
-
0:48
alpha, there we go, AlphaNumericChooser.java, there it is.
-
0:53
Okay, so let's go over some key concepts here.
-
0:57
First off, this extends a class called AbstractChooser.
-
1:01
Let's open that up too.
-
1:04
This might be the first time you've seen this keyword here, abstract.
-
1:09
What this means, basically, is that the class cannot be instantiated.
-
1:13
You must extend it and
-
1:15
override some required methods that are also marked with the abstract keyword.
-
1:20
See the icon over here?
-
1:22
This shows who uses the subclass, and
-
1:25
then down here this shows who implements each one of these methods.
-
1:28
So this one is an abstract method.
-
1:31
Okay, and you'll notice that over here it doesn't have any definition.
-
1:34
Just says what it throws.
-
1:38
But it's abstract, you must extend and override this.
-
1:41
Wow, so this class, this abstract class also has an inner class named Location.
-
1:49
Inner classes are helpful sometimes to create classes that depend on certain
-
1:53
variables in a surrounding class, or parent class.
-
1:57
Do you see here how it's using maxRows and maxColumns from the AbstracChooser class?
-
2:02
The AbstractChooser takes a maxRows and a maxColumns and that's the outside class.
-
2:06
And the inside class here, this location, uses the maxRows and the maxColumns,
-
2:11
because it's in the right scope.
-
2:13
Also look here, the constructor for Location is protected.
-
2:18
So no one other than the code in this package can create a location, only us.
-
2:24
So you've used something like this before, remember map.entry in the map interface?
-
2:29
It looks like all this is doing is grabbing a row and
-
2:32
column, validating that it's allowed, and then returning it.
-
2:37
It's a pretty dumb object, right?
-
2:39
Now, you might not have seen any of these concepts before, and
-
2:42
I wanted to use them to show you and reiterate, that doesn't matter.
-
2:47
You are testing the behavior, not the implementation, remember?
-
2:52
We're not gonna test that all that stuff is true,
-
2:55
we're just gonna test the behavior.
-
2:56
So let's just do that, right?
-
2:58
What is the happy path that comes out of here?
-
3:00
Well the public API says one thing,
-
3:04
It says locationFromInput, and it returns a location.
-
3:09
So how about we make sure that if we choose something valid
-
3:13
it returns the expected row and column, sound good?
-
3:16
So we wanna test the elementation specifically, so
-
3:19
let's switch over to the AlphanumericChooser.
-
3:22
So see we can mouse over here and here we'll jump back over there?
-
3:26
Cool.
-
3:27
So, let's create a new test over here, so again that's Cmd+Shift+T or
-
3:32
Shift+Ctrl+T in Windows.
-
3:34
And I'm gonna choose Create New Test.
-
3:38
JUnit four, it's got the right class name, it's in the right passage.
-
3:42
This time let's go ahead and let's make a before method.
-
3:44
And let's just go ahead and have it generate this test.
-
3:46
We're gonna rename it, we know that it's gonna give us a wrong name.
-
3:49
So let's go ahead and create that.
-
3:52
First things first, let's rename that.
-
3:54
Let's say validInputReturnsProperLocation.
-
4:03
All right, so how about in the Before up here
-
4:08
we have it create the chooser for us, right?
-
4:12
So we're gonna say, chooser= new AlphaNumericChooser.
-
4:17
And remember that that takes the max rows as 26 rows for the alphabet,
-
4:22
we'll just do that.
-
4:23
And then 10 columns that's a big vending machine.
-
4:27
Let's do that.
-
4:28
And it says can't resolve chooser, so
-
4:31
let's have it go ahead and create the field chooser for us.
-
4:35
Cool, okay, so we've got the arrange covered in the before method there,
-
4:39
now let's do the act.
-
4:41
So let's go ahead and get one of those locations out right,
-
4:45
that was that inner class.
-
4:46
We'll call it loc and we'll use the chooser that got instantiated and
-
4:50
we'll say location from input.
-
4:52
And let's just pass in the input, we'll pass in B4, and
-
4:57
now let's assert that we got the right location back.
-
5:02
So we want to make sure that B4 returns the second row,
-
5:07
right, A, B, and the fourth column.
-
5:10
So that's array indices 1 and 3, right?
-
5:15
Okay, so we're really only testing one behavior, but
-
5:18
we're probably gonna do it in two assert statements.
-
5:21
That's okay because we're testing the behavior.
-
5:23
There's two assert statements but it's the same behavior, right?
-
5:26
Okay, so let's do an assert,Equals, and
-
5:30
remember it goes expected and actual.
-
5:34
So we expect 1 for the row.
-
5:40
And we expect 2, or sorry, we expect 3 for the column, right?
-
5:44
So that's B4.
-
5:52
Cool, let's test it, awesome.
-
5:56
Here we can see our new test is showing up here and it looks like it passed, great.
-
6:00
It's kinda handy sometimes to always make sure that it fails too.
-
6:06
So cool, we can make sure that it fails.
-
6:09
You know what though?
-
6:10
Let's think about this, what if one these assertions,
-
6:12
one of these two assertions fail?
-
6:13
It's not gonna be obvious how it failed, right?
-
6:16
Let's break it and let's see.
-
6:17
All right, so if I say let's change this to 3.
-
6:24
It's just gonna say that it's an assertion error and expected 3 but it was 1.
-
6:28
But it's not clear, there's two assertions, not clear.
-
6:30
Is it talking about the row or is it talking about the column?
-
6:33
So this is a great use of the optional message parameter.
-
6:38
So what should do is you put on the positive version of what was expected.
-
6:41
So let's do that, so this would be here, this would be the proper row and
-
6:49
put in here, this is the proper column.
-
6:54
Okay, and then we refresh and run again, and we'll see that it says proper row.
-
7:01
So now, somebody, if this test fails,
-
7:02
they'll know, because of that message that we put in there, what that is.
-
7:06
It's a nice touch, right?
-
7:08
Fix that back.
-
7:12
There, now we know what's going on.
-
7:13
There are definitely more descriptive assertion patterns that we can use, and
-
7:17
are available to us, and we'll touch all those briefly here in a bit.
-
7:21
Looking at these class, if we come back here to this class,
-
7:24
there are some exceptions that are thrown in here.
-
7:27
We should probably try to test those too.
-
7:30
What a happy path we've found.
-
7:32
Exceptions are also part of the happy path.
-
7:34
So after this quick break,
-
7:35
let's learn how to properly test all expectations of our public facing API.
You need to sign up for Treehouse in order to download course files.
Sign up