Instant Mock Testing with PowerMock
Instant Mock Testing
with PowerMock Discover unit testing using PowerMock Deep Shah BIRMINGHAM - MUMBAIInstant Mock Testing with PowerMock Copyright © 2013 Packt Publishing All rights reserved. No part of this book may be reproduced, stored in a retrieval system, or
transmitted in any form or by any means, without the prior written permission of the publisher,
except in the case of brief quotations embedded in critical articles or reviews. Every effort has been made in the preparation of this book to ensure the accuracy of the information presented. However, the information contained in this book is sold withoutwarranty, either express or implied. Neither the author, nor Packt Publishing, and its dealers
and distributors will be held liable for any damages caused or alleged to be caused directly or
indirectly by this book.Packt Publishing has endeavored to provide trademark information about all of the companies
and products mentioned in this book by the appropriate use of capitals. However, Packt Publishing cannot guarantee the accuracy of this information.First published: October 2013 Production Reference: 1241013 Published by Packt Publishing Ltd. Livery Place
35 Livery Street Birmingham B3 2PB, UK.
ISBN 978-1-78328-995-0
www.packtpub.com
Credits
Author Project Coordinator Deep Shah Sherin Padayatty
Reviewer Proofreader Quentin Ambard Simran Bhogal
Clyde Jenkins Acquisition Editor
Rubal Kaur Production Coordinator
Alwin Roy Commissioning Editor
Govindan K Cover Work
Alwin Roy Technical Editor
Aparna Kumari Copy Editors
Alisha Aranha Kirti Pai Lavina Pereira
About the Author has been writing software for over a decade. As a child, he was always
Deep Shah fascinated by computers. As time passed, his fascination grew into passion, and he decided
to take up Software Development as a career choice. Deep has a degree in Computer Science
and is a big fan of open source software. Being a Software Developer at heart, he likes exploring new programming languages, tools, and frameworks.Deep strongly believes in writing unit tests. He thinks that any code (no matter when it’s
written) that does not have unit tests is legacy code. Deep has served stints with companies
such as Amazon, SpiderLogic, and ThoughtWorks. He speaks a number of languages including
Java, C#, JavaScript, Scala, and Haskell. In his free time, Deep likes to see the world, go to cool places, and click lots of pictures.I would like to thank Jayway and the Java Community for creating a great mocking framework. I cannot imagine finishing this book without the dedication and support of
my loving family, who put up with long nights and working weekends for far
longer than I had initially planned.About the reviewer uses PowerMock daily as a Java mock framework. He is currently the
Quentin Ambard
lead developer of the startup MyProcurement.fr, where he works with HBase and MongoDB, along with a bit of Scala on top of it. www.PacktPub.com
Support files, eBooks, discount offers and more
You might want to visitwww.PacktPub.com
for support files and downloads related to your book. Did you know that Packt offers eBook versions of every book published, with PDF and ePub and as a print files available? You can upgrade to the eBook version at www.PacktPub.com book customer, you are entitled to a discount on the eBook copy. Get in touch with us at for more details.
At , you can also read a collection of free technical articles, sign up for
www.PacktPub.com
a range of free newsletters and receive exclusive discounts and offers on Packt books and eBooks. TM
http://PacktLib.PacktPub.com
Do you need instant solutions to your IT questions? PacktLib is Packt’s online digital book library. Here, you can access, read and search across Packt’s entire library of books.
Why Subscribe? f Fully searchable across every book published by Packt f Copy and paste, print and bookmark content f On demand and accessible via web browser
Free Access for Packt account holders If you have an account with Packt at , you can use this to access
www.PacktPub.com
PacktLib today and view nine entirely free books. Simply use your login credentials for immediate access.
Table of Contents
Preface PowerMock is an open source mocking library for the Java world. It extends the existing
mocking frameworks, such as EasyMocks (see ) and Mockito
http://www.easymock.org/
(see ), to add even more powerful features
http://code.google.com/p/mockito/ to them.
PowerMock was founded by Jayway (see ) and is hosted on
http://www.jayway.com/
Google Code (see ).
http://code.google.com/p/powermock/
It has a vibrant community with a lot of contributors. Conscious efforts have been made to ensure that PowerMock does not reinvent the wheel. It only extends existing mocking frameworks and adds features that are missing from them. The end result is a mocking library that is powerful and is a pleasure to use.
Sometimes, a good design might have to be tweaked to enable testability. For example, use
of final classes or methods should be avoided, private methods might need to open up a bit
by making them package-visible or protected, and use of static methods should be avoidedat all costs. Sometimes these decisions might be valid, but if they are taken only because of
limitations in existing mocking frameworks, they are incorrect. PowerMock tries to solve this
problem. It enables us to write unit tests for almost any situation.What this book covers
Saying Hello World! (Simple) explains a basic mocking example using PowerMock. It will help
us get familiarized with basic mocking and verification syntax.
Getting and installing PowerMock (Simple) demonstrates the steps for setting up PowerMock
using IntelliJ IDEA and Eclipse. It also briefly describes other ways of setting up the PowerMock environment. Mocking static methods (Simple) shows how effortlessly we can mock static methods withPowerMock. Most of the mocking frameworks have trouble mocking static methods. But for
Power Mock, it’s just another day at work.Preface Verifying method invocation (Simple) explains various ways in which we can verify a certain method invocation. Verification is an indispensable part of unit testing. Mocking final classes or methods (Simple) covers how easily we can mock final classes or methods. Mocking final classes or methods is something that most mocking frameworks struggle with. Because of this restriction, sometimes a good design is sacrificed. Mocking constructors (Medium) introduces the art of mocking constructors. Is a class doing too much in its constructor? With PowerMock, we can mock the constructor and peacefully write tests for our own code. Understanding argument matchers (Medium) demonstrates how to write flexible unit tests
using argument matchers. Only verifying that a certain method was invoked is a job half done.
Asserting that it was invoked with correct parameters is equally important. Understanding the Answer interface (Advanced) demonstrates the use of theAnswer
interface, using which we can create some unusual mocking strategies. Sometimes mocking
requirements are extremely complex, which makes it impractical to create mocks in the traditional way. The interface can be used for such cases.Answer
Partial mocking with spies (Advanced) explains the steps to mock only a few methods of a given class while invoking the real implementation for all other methods. This is achieved in PowerMock by creating spies. Mocking private methods (Medium) covers the steps to mock and verify private methods.
Private methods are difficult to test with traditional mocking frameworks. But for PowerMock,
it’s a piece of cake.Breaking the encapsulation (Advanced) shows how we can test the behavior of a private class. At times, a private method and verifies the internal state of a class using the Whitebox
method might be performing an important business operation, and we need to write unit tests
for that method. The class can be very handy in such situations.Whitebox
Suppressing unwanted behavior (Advanced) explains how we can suppress unwanted behavior, such as static initializers, constructors, methods, and fields. Understanding Mock Policies (Advanced) demonstrates the use of Mock Policies to manage the repeated code needed to set up mocks for a complex object better. Listening with listeners (Medium) demonstrates the steps to listen for events from the test
framework. We might want to do some processing when the test method is invoked or create
a report about how many tests were run, how many passed, how many failed, and so on. Listeners are a good fit for such requirements.The Understanding Mock Policies (Advanced) and Listening with listeners (Medium) recipes are available for download from the Packt Publishing website,
http://www.packtpub. com/sites/default/files/downloads/Bonus_Recipes.pdf
2
Preface What you need for this book For setting up PowerMock, we will need JDK 6 or a later version installed on the machine.
The detailed instructions to download and install JDK 6 or a later version can be found at .
http://www.oracle.com/technetwork/java/javase/downloads/index.html
In addition, we will need an Integrated Development Environment (IDE) to write unit tests with
PowerMock effectively. This book covers the steps to integrate PowerMock with Eclipse and IntelliJ IDEA. Download and install any one of your favorite IDEs from forhttp://www.jetbrains.com/idea/ IntelliJ IDEA, and for Eclipse. http://www.eclipse.org/
Who this book is for
Written specifically for new users of PowerMock with little or no experience, this book will also
help users of other mocking libraries to get familiar with PowerMock concepts. It also covers
advanced PowerMock concepts for people with intermediate knowledge of PowerMock.Conventions
In this book, you will find a number of styles of text that distinguish between different kinds of
information. Here are some examples of these styles, and an explanation of their meaning.Code words in text are shown as follows: “We can include other contexts through the use of the directive.”
include
A block of code is set as follows:
public class EmployeeController { private EmployeeService employeeService; public EmployeeController(EmployeeService employeeService) { this.employeeService = employeeService; }
3
Preface
When we wish to draw your attention to a particular part of a code block, the relevant lines or
items are set in bold:public class EmployeeController {
private EmployeeService employeeService;
public EmployeeController(EmployeeService employeeService) { this.employeeService = employeeService; }
New terms and important words are shown in bold. Words that you see on the screen, in
menus or dialog boxes for example, appear in the text like this: “clicking on the Next button
moves you to the next screen”.Warnings or important notes appear in a box like this.
Reader feedback Feedback from our readers is always welcome. Let us know what you think about this book—what you liked or may have disliked. Reader feedback is important for us to develop titles that you really get the most out of. To send us general feedback, simply send an e-mail to , and
[email protected] mention the book title via the subject of your message.
If there is a topic that you have expertise in and you are interested in either writing or contributing to a book, see our author guide on .
www.packtpub.com/authors
Customer support
Now that you are the proud owner of a Packt book, we have a number of things to help you to
get the most from your purchase.Downloading the example code
You can download the example code files for all Packt books you have purchased from your
account at . If you purchased this book elsewhere, you canhttp://www.packtpub.com
visit
http://www.packtpub.com/support
and register to have the files e-mailed directly to you.
4
Preface Errata Although we have taken every care to ensure the accuracy of our content, mistakes do happen. If you find a mistake in one of our books—maybe a mistake in the text or the code—we would be grateful if you would report this to us. By doing so, you can save other readers from frustration and help us improve subsequent versions of this book. If you find any errata, please report them by visiting
,
http://www.packtpub.com/submit-errata
selecting your book, clicking on the errata submission form link, and entering the details of
your errata. Once your errata are verified, your submission will be accepted and the errata will
be uploaded on our website, or added to any list of existing errata, under the Errata section of
that title. Any existing errata can be viewed by selecting your title from.
http://www.packtpub.com/support
Piracy
Piracy of copyright material on the Internet is an ongoing problem across all media. At Packt,
we take the protection of our copyright and licenses very seriously. If you come across any illegal copies of our works, in any form, on the Internet, please provide us with the location address or website name immediately so that we can pursue a remedy.Please contact us at with a link to the suspected pirated
[email protected] material.
We appreciate your help in protecting our authors, and our ability to bring you valuable content.
Questions You can contact us at if you are having a problem with any
[email protected] aspect of the book, and we will do our best to address it.
5
Instant Mock Testing with PowerMock Welcome to Instant Mock Testing with PowerMock. This book will demonstrate the effective use of this versatile open source mocking framework. The recipes described in this book will introduce most of the concepts of PowerMock (see
http://code.google.com/p/ ) that will enable us to use it effectively. powermock/
PowerMock enables us to write good unit tests for even the most untestable code. Most of the mocking frameworks in Java cannot mock static methods or final classes. But using PowerMock, we can mock almost any class. PowerMock does not intend to reinvent the wheel. It extends existing frameworks such as EasyMocks (see ) and Mockito (see
http://www.easymock.org/ http://code.google.
) to enable us to do some of the things that these frameworks cannot.
com/p/mockito/ Because of this, PowerMock is extremely easy to learn and use.
The first part of the book will help us understand some of the basic mocking and verifying techniques using PowerMock. The later recipes will focus on writing unit tests for more complex scenarios.
PowerMock currently extends the EasyMock and Mockito mocking frameworks. Depending on which extension is preferred, the syntax to write any unit test differs slightly. All the features described in this book are supported using both these extensions, but in the interest of time and space, all the examples in this book will be developed using the PowerMock Mockito API.
Currently, PowerMock integrates with the JUnit (see http://junit. org/) and TestNG (see http://testng.org/doc/index.html) test frameworks. We will be using JUnit in all our examples.
Instant Mock Testing with PowerMock Saying Hello World! (Simple)
Unit testing enables us to test small bits of code in isolation. This essentially enables us to test the behavior and functionality of our system in a very granular way.
Let's say that we want to write unit tests for a piece of code that converts an employee name
to uppercase and writes it to a database. There are two ways in which we can test this: f Assert that the code converts the employee name to uppercase and also verify that it gets written to the database. In this approach we verify two things:
The business logic of converting the employee name to uppercase
The fact that it gets written to the database correctly To verify the second statement, we need to make sure that the database is available when the test is executing. We are essentially testing the integration of our code with the database system. This approach of testing is different from unit testing and is called integration testing. f Assert that the code converts the employee name to uppercase and verify that a call was made to the database to write this information. In this approach we verify twothings (which are slightly different from what we verify in the first approach):
The business logic of converting the employee name to uppercase
The fact that we made a call to write this information to the database In this approach, we do not actually go to the database and check if the employee name was successfully written. We only verify that a call was made to write this information to the database. It's clear by now that we cannot work with the actual database in this approach. This is when mocking comes into the picture. Mocks are nothing but simulated objects that can mimic the behavior of real objects.This recipe will demonstrate a very simple mocking example using PowerMock. It will show us
the basic syntax for creating a mock and verifying a method invocation.How to do it...
1. Let's say that we have a very simple class. As the name
EmployeeController
suggests, this class performs the Create, Read, Update, and Delete (CRUD)
operations on the class.Employee
2. This class delegates the heavy lifting to the class to actually
EmployeeService perform these operations.
Instant Mock Testing with PowerMock
3. Here's the code:
/**
- This is a very simple employee controller
- which will make use of the EmployeeService to
- perform Create, Read, Update and Delete (CRUD) * of Employee objects.
- It delegates the heavy lifting to the
- EmployeeService class
- @author Deep Shah */ public class EmployeeController { private EmployeeService employeeService; public EmployeeController(EmployeeService employeeService) { this.employeeService = employeeService; } /**
- This method is responsible to return the * projected count of employees in the system.
- Let's say the company is growing by 20% every year,
- then the project count of employees is 20% more than * the actual count of employees in the system.
- We will also round it off to the ceiling value.
- @return Total number of projected employees in the system.
- / public int getProjectedEmployeeCount() { final int actualEmployeeCount = employeeService.getEmployeeCount(); return (int) Math.ceil(actualEmployeeCount * 1.2); } /**
- This class is responsible to handle the CRUD * operations on the Employee objects.
- @author: Deep Shah */ public class EmployeeService {
Instant Mock Testing with PowerMock
/**
- This method is responsible to return * the count of employees in the system.
- Currently this method does nothing but * simply throws an exception.
- @return Total number of employees in the system.
- / public int getEmployeeCount() { throw new UnsupportedOperationException(); } }
4. Let's write the unit test for the method of
getProjectedEmployeeCount . EmployeeController
5. Currently, the method of throws an
getEmployeeCount EmployeeService
exception. Hence, we will need to mock the instance used by
EmployeeService . EmployeeController
6. Here is how the test code would look like:
/**
- The class that holds all unit tests for * the EmployeeController class.
- @author: Deep Shah */ public class EmployeeControllerTest { @Test public void shouldGetCountOfEmployees() { EmployeeController employeeController = new EmployeeController(new EmployeeService()); Assert.assertEquals(10, employeeController.getEmployeeCount()); } }
7. The preceding test creates an instance of by passing the
EmployeeController
reference of . It then asserts that the count of employees is equal
EmployeeService to .
10 8.
If we run the preceding test without any modification, the test case should fail with an instance of .
UnsupportedOperationException 9.
. We would also need to
EmployeeService
To fix the test, we will need to mock
mock the method of to return the value
getEmployeeCount EmployeeService
, which will then be bumped up by 20%, and the value will be returned from the
8 10 controller. This is what is asserted by our test.
Instant Mock Testing with PowerMock
10. Here's how we could do it using PowerMock:
@Test public void shouldReturnProjectedCountOfEmployeesFromTheService() { //Creating a mock using the PowerMockito.mock //method for the EmployeeService class. EmployeeService mock = PowerMockito.mock(EmployeeService.class); //Next statement essentially says that when //getProjectedEmployeeCount method //is called on the mocked EmployeeService instance, //return 8. PowerMockito.when(mock.getEmployeeCount()) .thenReturn(8); EmployeeController employeeController = new EmployeeController(mock); Assert.assertEquals(10, employeeController .getProjectedEmployeeCount()); } 11. If we now run the above test, it would pass.
12. Let's look at one more method in :
EmployeeController /** * This method saves the employee instance.
- It delegates this task to the employee service.
- @param employee the instance to save.
- / public void saveEmployee(Employee employee) { employeeService.save(employee); }
13. This new method is called ; its responsibility is to save the employee
saveEmployee
instance. It achieves this by delegating this responsibility to .
EmployeeService
14. This method does not return any value. Hence, the unit test for this controller method
has to simply assert that the method on thesaveEmployee EmployeeService instance was called.
15. The test for this method is as follows:
@Test public void shouldInvokeSaveEmployeeOnTheServiceWhileSavingTheEmployee() { EmployeeService mock = PowerMockito.mock(EmployeeService.class);
Instant Mock Testing with PowerMock
EmployeeController employeeController = new EmployeeController(mock); Employee employee = new Employee(); employeeController.saveEmployee(employee); //Verifying that controller did call the //saveEmployee method on the mocked service instance.
Mockito.verify(mock).saveEmployee(employee); }
16. This test is very similar to the previous test we saw. It creates a mock of , and then constructs the instance of .
EmployeeSerivce EmployeeController It then invokes the method on the controller. saveEmployee
17. What is more interesting is the last statement. In the last statement, we are
asserting that the method was called on the mocked instance of
saveEmployee . If we run the test, it will pass. EmployeeService
18. Notice that to verify the method was invoked on the mocked
saveEmployee
instance of , we are using . This shows how
EmployeeService Mockito.verify
PowerMock does not reinvent the wheel. It essentially extends the functionality of the existing mocking frameworks.
19. To verify that the test case is actually asserting what it's supposed to assert, comment the call to the method of and rerun
saveEmployee EmployeeService the test.
//employeeService.saveEmployee(employee);
20. Running the test after this change hits us with a failure. The failure message is as
follows:Wanted but not invoked: employeeService.saveEmployee( com.gitshah.powermock.Employee@276bab54);
- > at com.gitshah.powermock.EmployeeControllerTest .shouldInvokeSaveEmployeeOnTheServiceWhileSaving TheEmployee(EmployeeControllerTest.java:39) Actually, there were zero interactions with this mock. ...
21. Even the failure message is extremely easy to read and understand. It tells us that
we were expecting the method of the class
saveEmployee EmployeeService
will be called. However, there were zero interactions with that mocked instance of
.EmployeeService
Instant Mock Testing with PowerMock
MockSettings
:
MockSettings
5. Here's an example of using
4. Register a listener for notifying method invocations on the mock.
3. Enabling verbose logging: This can be helpful while debugging a test. It can be used to find incorrect interactions with the mock.
.
https://groups.google.com/ forum/?fromgroups=#!topic/mockito/YM5EF0x90_4
2. Creating mocks that implement extra interfaces: This can be helpful to cover
some corner cases; for more information, visitwe can do the following: 1. Naming the mocks: This can be helpful while debugging.
MockSettings
is rarely used. Using
MockSettings
MockSettings as an argument.
Downloading the example code You can download the example code files for all Packt books you have purchased from your account at http://www.PacktPub.com. If you purchased this book elsewhere, you can visit http://www.PacktPub. com/support and register to have the files e-mailed directly to you.
method has a couple of overloads. One of the overloads takes in
PowerMockito.mock
The
There's more...
method is used to verify that a certain method was invoked on the mocked instance.
Mockito.verify
The
PowerMockito.when method.
This mocked instance can be programmed to return dummy data on the occurrence of a certain event (such as method invocation). To set up the dummy data, we have to use the
PowerMockito.mock .
To create a mocked instance of any class, we can use
How it works...
@Test public void shouldInvokeSaveEmployeeOnTheServiceWhile SavingTheEmployeeWithMockSettings() { EmployeeService mock = PowerMockito.mock(EmployeeService.class, Mockito .withSettings() .name("EmployeeServiceMock") .verboseLogging());
Instant Mock Testing with PowerMock
EmployeeController employeeController = new EmployeeController(mock); Employee employee = new Employee(); employeeController.saveEmployee(employee); //Verifying that controller did call the //saveEmployee method on the mocked service //instance.
Mockito.verify(mock).saveEmployee(employee); }
6. The preceding code will set up the name of the mocked object as , and enable verbose logging.
EmployeeServiceMock
Getting and installing PowerMock (Simple) This recipe will describe the steps for setting up PowerMock in two major Integrated
Development Environments (IDEs): IntelliJ IDEA (see )
http://www.jetbrains.com/idea/ and Eclipse (see ). http://www.eclipse.org/
Getting ready
For setting up PowerMock, we will need JDK 6 or the later versions installed on the machine.
The detailed instructions on downloading and installing JDK 6 or a later version can be found
at .http://www.oracle.com/technetwork/java/javase/downloads/index.html
Download and install any one of your favourite IDEs from
http://www.jetbrains.com/ for IntelliJ IDEA and for Eclipse. idea/ http://www.eclipse.org/ How to do it...
1. PowerMock is an open source mocking framework that is under active development.
At the time of writing this book, PowerMock 1.5 was the most recent stable release.
2. Let's start by downloading PowerMock 1.5. Visit PowerMock home at http://code.
.
google.com/p/powermock/
3. PowerMock is hosted on Google Code. Click on the Downloads Tab on the page and you should see something as follows:
Instant Mock Testing with PowerMock
4. Since we are going to develop all our examples using the Mockito extension and JUnit test framework, download the
powermock- mockito-junit-1.5.zip file from http://code.google.com/p/ powermock/downloads/detail?name=powermock-mockito-junit-
.
1.5.zip&can=2&q=&sort=summary 5.directory.
$HOME/powermock-mocks-on-steroids/lib
Extract the ZIP file in the This ZIP file has all the dependent JAR files that we will need for writing unit tests with PowerMock.
6. Now let's set up PowerMock in IntelliJ IDEA.
7. Open IntelliJ IDEA. You should see a screen similar to the following screenshot:
Instant Mock Testing with PowerMock
8. Start by clicking on Create New Project. It will ask us what type of project we want
to create. Select Java Module from the left pane. Enterpowermock-mocks-on- steroids
in the Project name text field, and set the Project location as
$HOME/ powermock-mocks-on-steroids
:
9. Clicking on Finish will open up the project with the project structure displayed on the
left side. Notice that IntelliJ IDEA should have added thesrc folder automatically.
10. Next, let's add PowerMock and other dependent JARs to the project.
11. Right-click on the project and select Open Module Settings from the context menu.
12. This should open up a dialog window. In the dialog window, click on the Dependencies tab on the right side. This is how your screen should look like:
Instant Mock Testing with PowerMock
13. Press ALT + Insert. This should open up a small pop up; on the pop up select Jars or
directories....
14. This should open up a dialog that looks similar to the Windows Explorer. Navigate to
the path$HOME/powermock-mocks-on-steroids/lib
, select all the JAR files (which we extracted in Step 5), and click on OK. This is how your screen should look:
Instant Mock Testing with PowerMock
15. Click on the Sources tab in the module settings dialog. Right-click on the right-most
bottom panel. This should open up a context menu, from this menu click on New
Folder.... It should look very similar to the following screenshot: 16. This should open up a dialog to enter the folder name; enter .test
17. Click on the folder in the module settings dialog, and mark it as Test Sources.
test Close the module settings dialog.18. and
Create the source files EmployeeController.java EmployeeService.
with only the method (from the Saying Hello World!java getEmployeeCount (Simple) recipe) under the folder in the package. src com.gitshah.powermock 19.
with the method
EmployeeControllerTest.java
Create the test file (from the Saying Hello
shouldReturnCountOfEmployeesFromTheService
World! (Simple) recipe.) under the folder in the
test com.gitshah.powermock package.
20. Right-click on the
EmployeeControllerTest.java
file, and click on Run 'EmployeeControllerTest'. This should compile the project and run the unit test. If everything is set up correctly, we should see a screen that looks like the following screenshot, which indicates that the test passed.
Instant Mock Testing with PowerMock 21. Now, let's set up PowerMock in Eclipse.
22. Open Eclipse and click on the small down arrow next to the new icon on the toolbar.
This opens up a context menu. In the menu click on Java Project. The context menu should look as follows:
23. This opens up the Create Java Project wizard. In the first step, enter the project name as , and click on Next. This should show the Java
powermock-mocks-on-steroids Settings dialog.
Instant Mock Testing with PowerMock
24. On the Source tab, click on the Create new source folder link and create the
src
and folders. The end result should look something like:
test
25. Click on Finish, Eclipse should now open the project and you should see the Project
Explorer on the left side.26. and Create the source files EmployeeController.java EmployeeService.java
with only the method (from the Saying Hello World! (Simple)
getEmployeeCount recipe) under the folder in the package. src com.gitshah.powermock 27.
with the method
EmployeeControllerTest.java
Create the test file (from the Saying Hello
shouldReturnCountOfEmployeesFromTheService
World! (Simple) recipe) under the folder in the
test com.gitshah.powermock package.
28. Right-click on the
EmployeeControllerTest.java file, and click on Run As.
This opens up a smaller submenu, from the submenu select JUnit Test. This should compile the project and run the unit test. If everything is set up correctly, we should see that the test passes.
Instant Mock Testing with PowerMock There's more...
PowerMock provides various other ways in which it can be installed.
Maven integration Maven (see ) is a software project management and
http://maven.apache.org/ build tool.
Add the following XML snippet to for integrating PowerMock Mockito API with JUnit:
pom.xml <properties> <powermock.version>1.5.1</powermock.version> </properties> <dependencies> <dependency> <groupId>org.powermock</groupId> <artifactId>powermock-module-junit4</artifactId> <version>${powermock.version}</version> <scope>test</scope> </dependency> <dependency> <groupId>org.powermock</groupId> <artifactId>powermock-api-mockito</artifactId> <version>${powermock.version}</version> <scope>test</scope> </dependency> </dependencies>
Follow the links on the
http://code.google.com/p/powermock/wiki/ page under the Maven setup heading to integrate PowerMock with Maven. GettingStarted
Instant Mock Testing with PowerMock Other integration options f
PowerMock provides prebuild ZIP files for integrating the TestNG test framework and EasyMock extension API. f
http://code.google.com/p/powermock/
These ZIP files can also be found at .
downloads/list f The installation process is very similar to the one described here.
Mocking static methods (Simple) The real power of PowerMock is the ability to mock things that other frameworks can't.
One such thing is mocking static methods. In this recipe we will see how easily we can mock static methods.
Getting ready The use of static methods is usually considered a bad Object Oriented Programming practice, but if we end up in a project that uses a pattern such as active record (see
), we will end up
http://en.wikipedia.org/wiki/Active_record_pattern having a lot of static methods.
In such situations, we will need to write some unit tests and PowerMock could be quite handy.
Start your favorite IDE (which we set up in the Getting and installing PowerMock (Simple) recipe), and let's fire away.How to do it...
1. We will start where we left off. In the
EmployeeService.java
file, we need to implement the method; currently it throws an instance of
getEmployeeCount . UnsupportedOperationException
2. Let's implement the method in the class; the updated classes
EmployeeService
are as follows:
/**
- This class is responsible to handle the CRUD * operations on the Employee objects.
- @author Deep Shah */ public class EmployeeService { /**
Instant Mock Testing with PowerMock
- This method is responsible to return * the count of employees in the system.
- It does it by calling the * static count method on the Employee class.
- @return Total number of employees in the system.
- / public int getEmployeeCount() { return Employee.count(); } } /**
- This is a model class that will hold * properties specific to an employee in the system.
- @author Deep Shah */ public class Employee { /**
- The method that is responsible to return the * count of employees in the system.
- @return The total number of employees in the system.
- Currently this * method throws UnsupportedOperationException.
- / public static int count() { throw new UnsupportedOperationException(); } }
3. The method of calls the static method
getEmployeeCount EmployeeService
of the class. This method in turn throws an instance of
count Employee
.
UnsupportedOperationException4. To write a unit test of the method of ,
getEmployeeCount EmployeeService we will need to mock the static method of the class. count Employee 5.
in the directory.
EmployeeServiceTest.java test
Let's create a file called This class is as follows:
/**
- The class that holds all unit tests for * the EmployeeService class.
- @author Deep Shah
Instant Mock Testing with PowerMock
- / @RunWith(PowerMockRunner.class) @PrepareForTest(Employee.class) public class EmployeeServiceTest { @Test public void shouldReturnTheCountOfEmployees UsingTheDomainClass() { PowerMockito.mockStatic(Employee.class);
PowerMockito.when(Employee.count()).thenReturn(900); EmployeeService employeeService = new EmployeeService(); Assert.assertEquals(900, employeeService.getEmployeeCount()); } }
6. If we run the preceding test, it passes. The important things to notice are the two annotations ( and ) at the top of the class, and the
@RunWith @PrepareForTest call to the method. PowerMockito.mockStatic
The statement tells JUnit to
@RunWith(PowerMockRunner.class) execute the test using .
PowerMockRunner
The statement tells PowerMock
@PrepareForTest(Employee.class)
to prepare the class for tests. This annotation is required when
Employee
we want to mock final classes or classes with final, private, static, or native methods. The statement tells
PowerMockito.mockStatic(Employee.class)
PowerMock that we want to mock all the static methods of the
Employee class.
The next statements in the code are pretty standard, and we have looked at them earlier in the Saying Hello World! (Simple) recipe. We are basically setting up the static method of the class to return .
count Employee 900
Finally, we are asserting that when the method on the
getEmployeeCount
instance of is invoked, we do get back.
EmployeeService 900
7. Let's look at one more example of mocking a static method; but this time, let's mock
a static method that returns .void
8. We want to add another method to the class that will increment
EmployeeService
the salary of all employees (wouldn't we love to have such a method in reality?).
9. Updated code is as follows:
/**
Instant Mock Testing with PowerMock
- This method is responsible to increment the salary * of all employees in the system by the given percentage.
- It does this by calling the static giveIncrementOf method * on the Employee class.
- @param percentage the percentage value by which
- salaries would be increased * @return true if the increment was successful.
- False if increment failed because of some exception * otherwise.
- / public boolean giveIncrementToAllEmployeesOf(int percentage) { try{ Employee.giveIncrementOf(percentage); return true; } catch(Exception e) { return false; } }
10. The static method is as follows:
Employee.giveIncrementOf /**
- The method that is responsible to increment * salaries of all employees by the given percentage.
- @param percentage the percentage value by which
- salaries would be increased
- Currently this method throws * UnsupportedOperationException.
- / public static void giveIncrementOf(int percentage) { throw new UnsupportedOperationException(); }
11. The earlier syntax would not work for mocking a void static method. The test case that mocks this method would look like the following:
@RunWith(PowerMockRunner.class) @PrepareForTest(Employee.class) public class EmployeeServiceTest { @Test public void shouldReturnTrueWhenIncrementOf10 PercentageIsGivenSuccessfully() { PowerMockito.mockStatic(Employee.class);
PowerMockito.doNothing().when(Employee.class); Employee.giveIncrementOf(10);
Instant Mock Testing with PowerMock
EmployeeService employeeService = new EmployeeService(); Assert.assertTrue(employeeService.giveIncrementTo AllEmployeesOf(10)); } @Test public void shouldReturnFalseWhenIncrementOf10 PercentageIsNotGivenSuccessfully() { PowerMockito.mockStatic(Employee.class);
PowerMockito.doThrow(new IllegalStateException()).when(Employee.class); Employee.giveIncrementOf(10);
EmployeeService employeeService = new EmployeeService(); Assert.assertFalse(employeeService.giveIncrementTo AllEmployeesOf(10)); } }