-
Notifications
You must be signed in to change notification settings - Fork 585
Mockito
- Introduction
- Supported Versions
- Maven Configuration
- Usage
- Mockito Inline Mock Maker
- Further Information
- Mockito 1.7
Basically, PowerMock provides a class called "PowerMockito" for creating mock/object/class and initiating verification, and expectations, everything else you can still use Mockito to setup and verify expectation (e.g. times(), anyInt()).
All usages require @RunWith(PowerMockRunner.class)
and @PrepareForTest
annotated at class level.
PowerMock version 2.0.0 and upper has support of Mockito 2. PowerMock version 1.7.0 and upper has experimental support of Mockito 2.
A lot of issues are not resolved still. PowerMock uses internal Mockito API, but at least it possible to use both mocking framework together.
Mockito | PowerMock |
---|---|
2.8.9+ | 2.x |
2.8.0-2.8.9 | 1.7.x |
2.7.5 | 1.7.0RC4 |
2.4.0 | 1.7.0RC2 |
2.0.0-beta - 2.0.42-beta | 1.6.5-1.7.0RC |
1.10.8 - 1.10.x | 1.6.2 - 2.0 |
1.9.5-rc1 - 1.9.5 | 1.5.0 - 1.5.6 |
1.9.0-rc1 & 1.9.0 | 1.4.10 - 1.4.12 |
1.8.5 | 1.3.9 - 1.4.9 |
1.8.4 | 1.3.7 & 1.3.8 |
1.8.3 | 1.3.6 |
1.8.1 & 1.8.2 | 1.3.5 |
1.8 | 1.3 |
1.7 | 1.2.5 |
In the examples below we don't use static imports for the method in the Mockito or PowerMockito API for better understanding of where the methods are located. However we strongly encourage you to statically import the methods in your real test cases for improved readability.
Notes: Mockito team added ability to mock mocking of final classes/methods in Mockito 2.1.0. PowerMock support this feature since PowerMock 1.7.0 (tested with Mockito 2.8.9). The feature can be enable with using PowerMock Configuration. If you use Mockito 2, it is recommended to use Mockito for mocking final methods/classes.
How to mock and stub:
- Add
@PrepareForTest
at class level.
@PrepareForTest(Static.class) // Static.class contains static methods
- Call
PowerMockito.mockStatic()
to mock a static class (usePowerMockito.spy(class)
to mock a specific method):
PowerMockito.mockStatic(Static.class);
- Just use Mockito.when() to setup your expectation:
Mockito.when(Static.firstStaticMethod(param)).thenReturn(value);
Note: If you need to mock classes loaded by the java system/bootstrap classloader (those defined in the java.lang or java.net etc) you need to use this approach.
Verification of a static method is done in two steps.
- First call
PowerMockito.verifyStatic(Static.class)
to start verifying behavior and then - Call the static method of the
Static.class
to verify. For example:
PowerMockito.verifyStatic(Static.class); // 1
Static.firstStaticMethod(param); // 2
Important: You need to call verifyStatic(Static.class)
per method verification.
Mockito matchers are may still applied to a PowerMock mock. For example, using custom argument matchers per mocked static method:
PowerMockito.verifyStatic(Static.class);
Static.thirdStaticMethod(Mockito.anyInt());
You can still use Mockito.VerificationMode (e.g Mockito.times(x)) with PowerMockito.verifyStatic(Static.class, Mockito.times(2))
:
PowerMockito.verifyStatic(Static.class, Mockito.times(1));
If not private do:
PowerMockito.doThrow(new ArrayStoreException("Mock error")).when(StaticService.class);
StaticService.executeMethod();
Note that you can do the same for final classes/methods:
PowerMockito.doThrow(new ArrayStoreException("Mock error")).when(myFinalMock).myFinalMethod();
For private methods use PowerMockito.when, e.g.:
when(tested, "methodToExpect", argument).thenReturn(myReturnValue);
@RunWith(PowerMockRunner.class)
@PrepareForTest(Static.class)
public class YourTestCase {
@Test
public void testMethodThatCallsStaticMethod() {
// mock all the static methods in a class called "Static"
PowerMockito.mockStatic(Static.class);
// use Mockito to set up your expectation
Mockito.when(Static.firstStaticMethod(param)).thenReturn(value);
Mockito.when(Static.secondStaticMethod()).thenReturn(123);
// execute your test
classCallStaticMethodObj.execute();
// Different from Mockito, always use PowerMockito.verifyStatic(Class) first
// to start verifying behavior
PowerMockito.verifyStatic(Static.class, Mockito.times(2));
// IMPORTANT: Call the static method you want to verify
Static.firstStaticMethod(param);
// IMPORTANT: You need to call verifyStatic(Class) per method verification,
// so call verifyStatic(Class) again
PowerMockito.verifyStatic(Static.class); // default times is once
// Again call the static method which is being verified
Static.secondStaticMethod();
// Again, remember to call verifyStatic(Class)
PowerMockito.verifyStatic(Static.class, Mockito.never());
// And again call the static method.
Static.thirdStaticMethod();
}
}
You can use PowerMockito to partially mock a method using PowerMockito.spy. Be careful (the following is taken from the Mockito docs and applies to PowerMockito as well):
Sometimes it's impossible to use the standard when(..)
method for stubbing spies. Example:
List list = new LinkedList();
List spy = spy(list);
//Impossible: real method is called so spy.get(0) throws IndexOutOfBoundsException (the list is yet empty)
when(spy.get(0)).thenReturn("foo");
//You have to use doReturn() for stubbing
doReturn("foo").when(spy).get(0);
Just use Mockito.vertify() for standard verification:
Mockito.verify(mockObj, times(2)).methodToMock();
Use PowerMockito.verifyPrivate(), e.g.
verifyPrivate(tested).invoke("privateMethodName", argument1);
This also works for private static methods.
Use PowerMockito.whenNew, e.g.
whenNew(MyClass.class).withNoArguments().thenThrow(new IOException("error message"));
Note that you must prepare the class creating the new instance of MyClass
for test, not the MyClass
itself. E.g. if the class doing new MyClass()
is called X then you'd have to do @PrepareForTest(X.class)
in order for whenNew
to work:
@RunWith(PowerMockRunner.class)
@PrepareForTest(X.class)
public class XTest {
@Test
public void test() {
whenNew(MyClass.class).withNoArguments().thenThrow(new IOException("error message"));
X x = new X();
x.y(); // y is the method doing "new MyClass()"
..
}
}
Use PowerMockito.verifyNew, e.g.
verifyNew(MyClass.class).withNoArguments();
Mockito matchers are may still applied to a PowerMock mock:
Mockito.verify(mockObj).methodToMock(Mockito.anyInt());
@RunWith(PowerMockRunner.class)
// We prepare PartialMockClass for test because it's final or we need to mock private or static methods
@PrepareForTest(PartialMockClass.class)
public class YourTestCase {
@Test
public void spyingWithPowerMock() {
PartialMockClass classUnderTest = PowerMockito.spy(new PartialMockClass());
// use Mockito to set up your expectation
Mockito.when(classUnderTest.methodToMock()).thenReturn(value);
// execute your test
classUnderTest.execute();
// Use Mockito.verify() to verify result
Mockito.verify(mockObj, times(2)).methodToMock();
}
}
(Available in PowerMock version 1.3.6+)
@RunWith(PowerMockRunner.class)
// We prepare PartialMockClass for test because it's final or we need to mock private or static methods
@PrepareForTest(PartialMockClass.class)
public class YourTestCase {
@Test
public void privatePartialMockingWithPowerMock() {
PartialMockClass classUnderTest = PowerMockito.spy(new PartialMockClass());
// use PowerMockito to set up your expectation
PowerMockito.doReturn(value).when(classUnderTest, "methodToMock", "parameter1");
// execute your test
classUnderTest.execute();
// Use PowerMockito.verify() to verify result
PowerMockito.verifyPrivate(classUnderTest, times(2)).invoke("methodToMock", "parameter1");
}
}
Feature available as of PowerMock 1.7.0
The Mockito team added the support for mocking of final classes/methods in Mockito 2.1.0. This feature can be enabled in PowerMock by adding the following file
src/test/resources/mockito-extensions/org.mockito.plugins.MockMaker
containing a single line:
mock-maker-inline
PowerMock implements its own MockMaker
which leads to incompatibility with Mockito mock-maker-inline
, even if PowerMock is just added as a dependency and not used. If two org.mockito.plugins.MockMaker
exist in path then any only one can be used, which one is undetermined.
PowerMock can however delegate calls to another MockMaker
, and for then tests are run without PowerMock.
Since PowerMock 1.7.0 this can be configured with using the PowerMock Configuration.
The MockMaker
can be configured by creating the file org/powermock/extensions/configuration.properties
and setting:
mockito.mock-maker-class=mock-maker-inline
Example of using Mockito mock-maker-inline
with PowerMock:
https://github.com/powermock/powermock-examples-maven/tree/master/mockito2
Have a look at the source in GitHub for examples. Also read the PowerMockito related blog at the Jayway team blog.