Lesson 3 of 21

Unit Testing Demo

Duration: 7:30 Watch on YouTube (external link, opens in new tab)

Markdown version

A short demo about jUnit basics.

In this lesson

In IntelliJ, Roy Osherove shows string calculator (external link, opens in new tab) tests that use helper methods (external link, opens in new tab) called make calc and assert adding to avoid repetition and keep the tests maintainable (external link, opens in new tab). He then compares ways to test that a line throws an exception in JUnit (external link, opens in new tab): a try/catch block, the expected parameter of the test annotation, which he advises against because any line can throw, and an expected exception rule (external link, opens in new tab). With the rule, only the lines after the expect call are supposed to throw the exception.

Transcript

890 words

[00:03] (external link, opens in new tab) Let me show you a little bit of features here. This is IntelliJ Let's see if I can just close others should be okay.

[00:36] (external link, opens in new tab) So what I'm showing here is a class called string calculator (external link, opens in new tab). So I have a package here called unit tests (external link, opens in new tab) and I have a class called string calculator. And there's a lot of logic but the logic is pretty simple. It basically parses out numbers and it checks if there are like negative numbers. It throws exception. If there's an empty input, then it returns a default value. And you'll notice that a lot of this is just calls to different smaller methods.

[01:11] (external link, opens in new tab) And what what happens is that usually with testdriven development, you start with something and you refactor into new methods. So what we're going to do is I just want to show you how the tests look. So I have a class called string calculator tests. I have a helper method (external link, opens in new tab) called make calc. And this is one of the reasons that I want to be able to have maintainability (external link, opens in new tab) is is achieved.

[01:41] (external link, opens in new tab) One of the ways to achieve maintainability is by not creating the string calculator directly in my tests but by having it directly called by a helper method. So this is an example of creating the calculator and I actually have a method called assert adding and in assert adding what I do is I basically have this little test right here. I started with a little test and I saw hey I keep repeating myself.

[02:14] (external link, opens in new tab) So maybe I'll just call add here and I will just assert against it and that will help me remove some of the repeating in the code. So I came up with a helper method. This is not a test but it does have an assert inside it. Another feature that's important is when we want to test

[02:47] (external link, opens in new tab) A line like this. Let's say if there's a number that's negative, throw an illegal argument exception. How do I test a line that throws an exception in JUnit (external link, opens in new tab)? Well, there are several ways. One way is to use try catch, but there are that's usually frowned upon these days. because it makes the test very very unreadable. Basically, if I wanted to, I would write something like this. Test public

[03:18] (external link, opens in new tab) Void add with negative rows. I just call it zero because they have different examples of that. And then here I would say try minus one. And here I might say catch

[03:48] (external link, opens in new tab) I could choose the exception and throwable E. And here I might say look if you got all the way to the exception all good. Okay, I can just say return. But if you got all the way out of the exception

[04:19] (external link, opens in new tab) And I can say assert false true, I can make the test fail on purpose and say expected exception (external link, opens in new tab). And that's an example of how you would how would you would make the test fail on purpose. I usually just say this because the name of the test is good enough that I don't have to give to give a good comment.

[04:52] (external link, opens in new tab) So that's the like the that used to be the the good way of doing things because you wanted to say okay this line is supposed to throw an exception but then with the latest version of JUnit I could just say test and say expected equals illegal argument exception.class. Don't use this. Okay, I'm showing you so that you know not to use this. And the reason is it's basically putting the whole test in a big try catch.

[05:24] (external link, opens in new tab) What's the problem with that? Means that any line can throw that exception. So if the wrong line throws an exception, something in the arrange part (external link, opens in new tab) for example, your test will actually pass. It will lie to you. Okay. So expected exception is something that exists that you should not use. Here's a bit of a cleaner way to do it. You create something called a rule. A rule is something that you can set that applies to all the tests. For example, I set a rule and then a public field expected exception and I call it thrown.

[05:59] (external link, opens in new tab) And I say the expect the default of expected exception is none. This is part of the JUnit APIs. And then in my test I would say make the calculator and then I would say thrown expect illegal argument exception.class. And here I would have that line. So now only the lines that appear after this line are the ones that are supposed to throw the exception. Okay.

[06:30] (external link, opens in new tab) Now why is that important? because it allows me to say that this line shouldn't throw an exception. If this line throws that exception, my test will fail. But if this line throws an exception, my test will pass. So I'm able to say that specific line is the important one. And if you if you if you don't like this rule, this working with rules, you can always go back to try catch. That's the And you'll notice that even in try catch you can actually make that mistake of saying oh just make the calc.

[07:02] (external link, opens in new tab) So here I'm just going to extract a variable from it. And now this line is the only nine that's supposed to throw an exception.