Lesson 17 of 21

Unconstrained Isolation Frameworks

Duration: 9:50 Watch on YouTube (external link, opens in new tab)

Markdown version

In this talk we learn what frameworks such as Powermock and JMockit (external link, opens in new tab) have to offer, both in terms of APIs and in terms of test readability (external link, opens in new tab) and maintinability.

In this lesson

Roy Osherove shows the static logger test written with PowerMock (external link, opens in new tab), Mockito and JUnit (external link, opens in new tab), using the run with annotation with the PowerMock runner, an annotation that loads the static logger class differently, and verify static before each verified call. He then shows the same tests in JMockit, which has to be loaded before JUnit and uses non-strict (external link, opens in new tab) expectations and verifications blocks. He does not usually recommend JMockit because calls are repeated twice and tests get wordy, and suggests starting the exercises with PowerMock.

Transcript

1,458 words

[00:02] (external link, opens in new tab) Let's talk about unconstrained frameworks (external link, opens in new tab). Up until now, what we did was we used extract and override (external link, opens in new tab) or using static class to to abstract away things that like time. Now let's talk about what happens if we cannot change our code using either refactoring or we don't own the code or we're afraid to change it. That's where tools like PowerMock come into play. So, PowerMock is an added extension that you can use with JUnit (external link, opens in new tab), with Mockito, with TestNG.

[00:34] (external link, opens in new tab) It's basically an addition that works with most other things. When you download it, you have many variations. We are going to use the variation that is the PowerMock with Mockito and JUnit. It has different variations for the frameworks that you would use. For example, if you're using EasyMock, you would use a different a different download. This is the test, the classic test of string calculator (external link, opens in new tab) that has to call a logger.

[01:06] (external link, opens in new tab) Only this time it's a static logger without the need to refactor. So the first thing we notice is that we have two special annotations at the top of the test. The first is run with which is part of JUnit and it tells us to use a different testr runner and here we would use PowerMock runner class. Now that's important because PowerMock under underneath will do a lot of magic quote unquote to

[01:36] (external link, opens in new tab) To basically manipulate bytes and class loaders so that it can inject behavior into any method it wants. And then we have to let PowerMock know that in this test we want to load a special version of static logger class. This basically loads the class differently in memory and what happens later is that in the test we have to

[02:07] (external link, opens in new tab) Fake (external link, opens in new tab) the static methods of static logger. So this is just loading it differently. This one tells PowerMock or in this case it's called PowerMockito because it's special extension for Mockito to fake the static methods of static logger. And this is all we have to do really from this moment on the static methods will not do anything but we can also verify on them. So we do this we mock all the statics but we actually I'm just saying we're faking them.

[02:37] (external link, opens in new tab) But we use one of them as a mock object. So to verify a static method we have to do two actions with PowerMock. We have to say that the next call is going to be a verification on a static method and then we actually do the call but we can use the matchers from ok from from JUnit and from Mockito. So in this case we're saying any string. So again this is basically our the first line of verify static tells PowerMockito that the next invocation on static logger is actually not real and it's an expectation.

[03:20] (external link, opens in new tab) That's why you need to do this for every call if you're going to verify multiple calls which is already a bad idea. Why do you know why is it a bad idea to verify multiple calls in a single test? more than one. >> It's testing more than one thing. Exactly. So you wouldn't need to have more than these two calls if you're verifying a static method because that's a single end result (external link, opens in new tab). But either way, you have to remember to say verify static and only then to do the call.

[03:52] (external link, opens in new tab) So that's the way that PowerMock works. And it's once you get used to it, it's actually pretty easy to do things. Here's how it would work with the JMockit. JMockit is a separate framework. You can write tests with it. It can run on top of the JUnit testr runner. But when you use the class library, you have to put the jar file in front of or before JUnit. So JMockit has to be loaded into memory before JUnit is loaded into memory.

[04:27] (external link, opens in new tab) That makes JMockit also load JUnit in a completely different way. So it can trace everything that's that gets called. Here is the same test with JMockit and you'll see that it looks completely different. First of all, we have two special sections in the test. The arrange part (external link, opens in new tab) looks like new non-strict (external link, opens in new tab) expectations. That's a special class that's part of JMockit. And in the non-strict expectations, we set up how we want fake things to behave.

[05:00] (external link, opens in new tab) And in the bottom we have verifications which are basically our verifications or asserts. So let's focus on one of them. When we look at the non-strict expectations when we have two types of expectations we have strict we have non-strict. We want the non-strict. Always remember that right? Because if we you we would have used the strict version of those we would say new new expectations. That's how it was called. And then anything that was not expected would break our test

[05:33] (external link, opens in new tab) Which is not what we want. We want that any number of things might be called. We just verify later what was called. However, you still have to tell JMockit what's going to happen. So even in the non-strict expectations even if I just want to make sure the static logger right was called I still have to say to JMockit to how do I call this interlace or what do you call when you go through a piece of code and you trace through it.

[06:10] (external link, opens in new tab) I don't remember the the exact name but basically to use static logger and to start verifying it in memory without this call I cannot verify on static logger.write Right? So I would have to make this call for each method that I might verify on. That's important because it means that I now have to repeat each method twice, which is not a good thing. Then in my verification, sorry. And I and then I can use a special constant called any string, which looks like any string from Okto, but it's not.

[06:43] (external link, opens in new tab) It's not a method if you notice. If I wanted to use matchers, like I don't want to have a hard-coded string to be expected here. Now when I want to verify I use new verifications and then I basically call static logger write and then I can use another example of matcher with substring of got one. So again I have to repeat the call twice when I use JMockit which is something that I specifically don't like and it's the reason why I don't usually recommend JMockit too much.

[07:15] (external link, opens in new tab) Although the syntax can grow on you, I don't like it because you have to your test becomes very wordy and you have to add a new line for each line you verify. Are there any questions so far? Okay. Let me see if I have a good demo for you guys. This is Java drills. This is Java demos.

[07:46] (external link, opens in new tab) I might have a slightly more interesting demos. Let's see. Let's see. Let's see. Unconstraight. Okay. So, here are the same tests again with J with the PowerMock. But what I wanted to show you specifically was the one with the JMockit. I wanted to show you how wordy it gets

[08:18] (external link, opens in new tab) When you want to have something that has one stub (external link, opens in new tab) and one mock object. So in this case, the test is logger throws call static web service. So I have non-strict expectations and then then I say something special static logger I define it and then I define these properties on it static logger.write with anything and then I say result equals new out of memory error. So this is how you would specify that something in JMockit would return an error.

[08:49] (external link, opens in new tab) You would say result after the call. There is another syntax called mockup which is even more complicated so I'm not even showing it here. And then for static web service you have to again do a definition and say notify is going to be called at some point and then you verify on static web service. Just look at how long the test becomes. So that's for example how you could do that and make something throw an error in JMockit. But that's also the reason that I don't like to use it too much.

[09:20] (external link, opens in new tab) It's very very worthy and it also repeats itself a lot of a lot of times. So if there aren't any questions, what I want you to do is I want you to repeat the exercises from the static logger from the beginning of making calls to the static logger. The first exercise of legacy code (external link, opens in new tab) and try to do them all with PowerMock or with JMockit whichever one you choose. I would recommend to start with PowerMock because I think it's more maintainable framework.