Can't suppress DriverManager's static init

2019-05-26 08:52发布

问题:

I have a unit test that attempts to create a SQLException to simulate a database error. In SQLException's constructor, there is a call to DriverManager, which has a static initialization block. I figured that I could suppress the static block with this type of setup:

@RunWith(PowerMockRunner.class)
@SuppressStaticInitializationFor({"java.sql.DriverManager"})
public class StaticTest 
{
    @Test
    public void testStaticSuppress() throws Exception
    {
        SQLException ex = new SQLException();
        expect(...).andThrow(ex);
    }
}

When I run the test, the static block in DriverManager is still called. What am I doing wrong?


Clarifications

  • I am running Powermock 1.5 - I was under the impression that using v1.5 allows me to mock system classes
  • When DriverManager runs it's static initialization block, I get this exception:

Oct 15, 2013 1:06:24 PM oracle.jdbc.driver.OracleDriver registerMBeans

WARNING: Error while registering Oracle JDBC Diagnosability MBean.

java.lang.LinkageError: loader constraint violation: when resolving method "java.lang.management.ManagementFactory.getPlatformMBeanServer()Ljavax/management/MBeanServer;" the class loader (instance of org/powermock/core/classloader/MockClassLoader) of the current class, oracle/jdbc/driver/OracleDriver, and the class loader (instance of ) for resolved class, java/lang/management/ManagementFactory, have different Class objects for the type javax/management/MBeanServer; used in the signature

  • I realize that I could make a mock of SQLException and never instantiate it directly. I would rather not go that route since it would mean updating 91 different unit tests. I asked the question because it looked like my code should work just fine according to the PowerMock docs.

回答1:

I suspect (but I am not certain) that Powermock is unable to prevent the static initializer from running for classes that are loaded by the system or bootstrap classloader (like the jre classes including those of the package java.sql are).


After posting to the Powermock Google Group, I got this response:

You can mock, suppress methods, stub methods etc in these classes since powermock 1.2.5 but you cannot suppress static initializers.



回答2:

See this page: Google Groups PowerMock Group

You need to add to the class: @PowerMockIgnore("javax.management.*")