Powermock is a mocking framework that
extends other mocking frame works like EasyMock and Mockito. Before discussing
about Powermock let us briefly discuss about unit testing, mocking.
Unit
Testing
Unit testing is a software testing
method by which, we can test each part of the program separately. The goal of
unit testing is to isolate each part of the program and show that the
individual parts are correct.
What
is mocking and why it is required?
Let’s consider following scenario.
There are 4 modules (Assume them like
classes), module1, module2, module3, and module4 in an Application. Let us
assume, you have a team of 4 members and assigned each module to every one.
There is a dependency on module4 for all other three modules1, 2 and 3. To make the
progress of Application faster, you assume that module4 will be implemented on
time and started developing modules1,2, 3 and 4 parallel. Unfortunately Module 4
is not implemented on time, it may take another 2 months to finish, but all
other modules 1 and 2 and 3 are finished and ready for testing. But you
can’t test the complete functionality of modules 1, 2 and 3, since they are
dependent on module4. All modules 1, 2 and 3 must wait until the module 4
finished, which is not feasible, here mocking came into picture. Mocking create
simulated objects that mimic the behavior of real objects. You create a mock
object for module4 (Assume that this functionality will be unit tested, after implementation)
and test other modules 1, 2, and 3.
The idea of unit testing is that you can
test your code without testing the dependencies and the code written by others.
This test allows you to verify that the code being tested works, regardless of its
dependencies. The idea is that if the code I write works as designed and my
dependencies work as designed, then they should work together as designed. This is explained by following example in detail.
Step 1: Create new maven project, mockito_tutorial.
Select the
check box “Create a new simple project (skip archetype selection).
Step 2: Open pom.xml, update dependency for mockito.
pom.xml
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>mockito_tutorial</groupId> <artifactId>mockito_tutorial</artifactId> <version>0.0.1-SNAPSHOT</version> <properties> <powermock.version>1.6.2</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> </project>
Step 3: Create a class “ConfigService.java” inside the
package com.src.configurations.
package com.src.configurations; public class ConfigService { public boolean testConfigurations(){ /** * Code is not implemented, may take 2 months to finish */ return true; } }
Step 4: Create a class Application.java inside the package com.src.application.
package com.src.application; import com.src.configurations.ConfigService; public class Application { public String runApplication(ConfigService service) { if (service.testConfigurations()) { return startApplication(); } else { return haltApplication(); } } private String startApplication() { return "Application started"; } private String haltApplication() { return "Application halted"; } }
Step 5: Create a class “ApplicationTest.java” inside the
package com.test.application.
package com.test.application; import static org.junit.Assert.assertEquals; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.runners.MockitoJUnitRunner; import org.powermock.api.mockito.PowerMockito; import com.src.application.Application; import com.src.configurations.ConfigService; @RunWith(MockitoJUnitRunner.class) public class ApplicationTest { @Test public void testRunApplication1() { Application application = new Application(); ConfigService service = PowerMockito.mock(ConfigService.class);; PowerMockito.when(service.testConfigurations()).thenReturn(true); String status = application.runApplication(service); assertEquals(status, "Application started"); } @Test public void testRunApplication2() { Application application = new Application(); ConfigService service = PowerMockito.mock(ConfigService.class);; PowerMockito.when(service.testConfigurations()).thenReturn(false); String status = application.runApplication(service); assertEquals(status, "Application halted"); } }
When a class
is annotated with @RunWith or extends a class annotated with @RunWith, JUnit
will invoke the class it references to run the tests in that class instead of
the runner built into JUnit.
Since testConfigurations()
is not implemented fully, we have to mock the testConfigurations() to finish
the testing of Application class. We can do this with following statement.
PowerMockito.when(service.testConfigurations()).thenReturn(false);
When
testConfigurations() is called, then it returns false, instead of original
implementation.
Step 6: Right click on ApplicationTest.java, Run as junit
test.
You will get
junit output like following.
Final
project structure looks like below.
No comments:
Post a Comment