Mocking static methods with Mockito
Use PowerMockito on top of Mockito.
Example code:
@RunWith(PowerMockRunner.class)
@PrepareForTest(DriverManager.class)
public class Mocker {
@Test
public void shouldVerifyParameters() throws Exception {
//given
PowerMockito.mockStatic(DriverManager.class);
BDDMockito.given(DriverManager.getConnection(...)).willReturn(...);
//when
sut.execute(); // System Under Test (sut)
//then
PowerMockito.verifyStatic();
DriverManager.getConnection(...);
}
More information:
- Why doesn't Mockito mock static methods?
How to Mock a static method with mockito?
Since static method belongs to the class, there is no way in Mockito to mock static methods. However, you can use PowerMock along with Mockito framework to mock static methods.
A simple class with a static method:
public class Utils {
public static boolean print(String msg) {
System.out.println(msg);
return true;
}
}
Class test mocking static method using Mockito and PowerMock in JUnit test case:
@RunWith(PowerMockRunner.class)
@PrepareForTest(Utils.class)
public class JUnit4PowerMockitoStaticTest{
@Test
public void test_static_mock_methods() {
PowerMockito.mockStatic(Utils.class);
when(Utils.print("Hello")).thenReturn(true);
when(Utils.print("Wrong Message")).thenReturn(false);
assertTrue(Utils.print("Hello"));
assertFalse(Utils.print("Wrong Message"));
PowerMockito.verifyStatic(Utils.class, atLeast(2));
Utils.print(anyString());
}
}
For more details see this link.
How to mock just one static method in a class using Mockito?
By default all methods are mocked. However, using Mockito.CALLS_REAL_METHODS
you can configure the mock to actually trigger the real methods excluding only one.
For example given the class Sample
:
class Sample{
static String method1(String s) {
return s;
}
static String method2(String s) {
return s;
}
}
If we want to mock only method1
:
@Test
public void singleStaticMethodTest(){
try (MockedStatic<Sample> mocked = Mockito.mockStatic(Sample.class,Mockito.CALLS_REAL_METHODS)) {
mocked.when(() -> Sample.method1(anyString())).thenReturn("bar");
assertEquals("bar", Sample.method1("foo")); // mocked
assertEquals("foo", Sample.method2("foo")); // not mocked
}
}
Be aware that the real Sample.method1()
will still be called. From Mockito.CALLS_REAL_METHODS
docs:
This implementation can be helpful when working with legacy code. When
this implementation is used, unstubbed methods will delegate to the
real implementation. This is a way to create a partial mock object
that calls real methods by default.
...
Note 1: Stubbing partial mocks using
when(mock.getSomething()).thenReturn(fakeValue)
syntax will call the
real method. For partial mock it's recommended to usedoReturn
syntax.
So if you don't want to trigger the stubbed static method at all, the solution would be to use the syntax doReturn
(as the doc suggests) but for static methods is still not supported:
@Test
public void singleStaticMethodTest() {
try (MockedStatic<Sample> mocked = Mockito.mockStatic(Sample.class,Mockito.CALLS_REAL_METHODS)) {
doReturn("bar").when(mocked).method1(anyString()); // Compilation error!
//...
}
}
About this there is an open issue, in particular check this comment.
Unable to mock System class static method using PowerMockito
java.net.InetAddress
is a system class. The caller of the system class should be defined in @PrepareForTest({ClassThatCallsTheSystemClass.class})
.
See documentation.
The way to go about mocking system classes are a bit different than
usual though. Normally you would prepare the class that contains the
static methods (let's call it X) you like to mock but because it's
impossible for PowerMock to prepare a system class for testing so
another approach has to be taken. So instead of preparing X you
prepare the class that calls the static methods in X!
Please note @InjectMocks
annotation does not inject static mocks, it can be removed.
Example of working test:
@RunWith(PowerMockRunner.class)
@PrepareForTest(SCUtil.class)
public class SCUtilTest {
private SCUtil scUtil = new SCUtil();
@Test(expected = ServiceException.class)
public void testCreateSC_Exception () throws UnknownHostException {
PowerMockito.mockStatic(InetAddress.class);
PowerMockito.when(InetAddress.getLocalHost()).thenThrow(new UnknownHostException("test"));
scUtil.createSC();
}
}
Related Topics
How Does the Java 'For Each' Loop Work
What Does the 'Static' Keyword Do in a Class
Downloading Java Jdk on Linux Via Wget Is Shown License Page Instead
Java Processbuilder: Resultant Process Hangs
How to Convert a String to an Int in Java
Calling Awt Frame Methods from Subclass
What Does "Could Not Find or Load Main Class" Mean
Java String to Date Conversion
Java Refuses to Start - Could Not Reserve Enough Space For Object Heap
Why Maven Uses Jdk 1.6 But My Java -Version Is 1.7
Eclipse/Tomcat: Deploy Doesn't Work Any More (Classnotfoundexception)
How Do Servlets Work? Instantiation, Sessions, Shared Variables and Multithreading
Why Does My Arraylist Contain N Copies of the Last Item Added to the List
Is Java "Pass-By-Reference" or "Pass-By-Value"
The Use of Multiple Jframes: Good or Bad Practice
How to Time a Method'S Execution in Java
Download a File With Android, and Showing the Progress in a Progressdialog