Reputation: 301
I'm trying to mockStatic DriverManager.class and get mockConnection but a real static void method is called getConnection instead.
Tests class:
@RunWith(PowerMockRunner.class)
@PrepareForTest(DriverManager.class)
public class MyClassTest {
@Before
public void setUp() throws Exception {
Connection connection = mock(Connection.class);
Statement statement = mock(Statement.class);
PowerMockito.mockStatic(DriverManager.class);
PowerMockito.doReturn(connection).when(DriverManager.class, "getConnection", anyString(), anyString(), anyString());
}
@Test
public void testMain() {
// arrange
String[] args = {"name", "password", "database"};
}
}
Pom.xml
<properties>
<powermock.version>1.7.4</powermock.version>
</properties>
<dependencies>
<!-- https://mvnrepository.com/artifact/junit/junit -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.11</version>
<scope>test</scope>
</dependency>
<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-mockito2</artifactId>
<version>${powermock.version}</version>
<scope>test</scope>
</dependency>
</dependencies>
Exception which I got when trying to execute PowerMockito.doReturn(connection).when(DriverManager.class, "getConnection", anyString(), anyString(), anyString()):
java.sql.SQLException: No suitable driver found for
at java.sql.DriverManager.getConnection(DriverManager.java:689)
at java.sql.DriverManager.getConnection(DriverManager.java:247)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.powermock.reflect.internal.WhiteboxImpl.performMethodInvocation(WhiteboxImpl.java:1846)
at org.powermock.reflect.internal.WhiteboxImpl.doInvokeMethod(WhiteboxImpl.java:810)
at org.powermock.reflect.internal.WhiteboxImpl.invokeMethod(WhiteboxImpl.java:790)
at org.powermock.reflect.Whitebox.invokeMethod(Whitebox.java:466)
at org.powermock.api.mockito.internal.expectation.PowerMockitoStubberImpl.when(PowerMockitoStubberImpl.java:110)
at vez.MyClassTest.setUp(MyClassTest.java:26)
What did I wrong? How to properly mock the DriverManager.class? PS. When I look into the org.powermock.api.mockito.internal.expectation.PowerMockitoStubberImpl.when(PowerMockitoStubberImpl.java:110) I see that it always invoke "Whitebox.invokeMethod(classMock, methodToExpect, parameters);" Therefore I don't understand how it works in general.
Upvotes: 1
Views: 1776
Reputation: 301
The solution which works eventually when I create instance of the objectUnderTest and put its class name under @PrepareForTest annotation (disregard of warnings in the out console). Though I have no idea why it works this way:
@RunWith(PowerMockRunner.class)
@PrepareForTest(DriverManager.class, MyClass.class)
public class MyClassTest {
@Before
public void setUp() throws Exception {
Connection connection = mock(Connection.class);
Statement statement = mock(Statement.class);
PowerMockito.mockStatic(DriverManager.class);
PowerMockito.when(DriverManager.getConnection(anyString(), anyString(), anyString())).thenReturn(connection);
}
@Test
public void testMain() {
// arrange
String[] args = {"name", "password", "database"};
MyClass myClass = new MyClass();
myClass.method();
...
}
Upvotes: 1
Reputation: 1321
The DriverManager
class will attempt to load the driver classes referenced in the "jdbc.drivers"
system property as part of its initialization. This happens when the DriverManager
class is loaded, i.e., even before any method like getConnection()
is invoked. So its not that the exception you are getting is because a real getConnection()
is getting called. Its because you have not included a real driver class on the classpath, as is evident from your pom
, that DriverManager
can load during its initialization. So, include a driver in your pom
and then try.
Please see https://docs.oracle.com/javase/7/docs/api/java/sql/DriverManager.html and the static
block in the source code of DriverManager class at https://github.com/JetBrains/jdk8u_jdk/blob/master/src/share/classes/java/sql/DriverManager.java.
Upvotes: 3