开发者

JMockit NullPointerException on Exceptions block?

Having already spent a lot of time on this test and unable to reason my way out of it, i have no other choice than ask for your help :)

Using JMockit to test some of my own JDBC "Wrapper" classes, i came to a dead end.

This is the class im testing:

public class JdbcConnectionProperties {
    private Properties properties = new Properties();
    private String username;
    private String password;
    private String connectionString;

    public JdbcConnectionProperties(String propertiesFilePath) {
        loadProperties(propertiesFilePath);
    }

    public void setProperties() {
        username = properties.getProperty("user");
        password = properties.getProperty("password");

        String connectionType = properties.getProperty("connection_type");
        String serverAddress = properties.getProperty("server_address");
        String port = properties.getProperty("port");
        String sid = properties.getProperty("sid");

        //Create a connection string
        connectionString = "jdbc:oracle:" + connectionType + ":@" + serverAddress + ":" + port + ":" + sid;
    }


    private void loadProperties(String propertiesFilePath) {
        String filePath = Thread.currentThread().getContextClassLoader().getResource(propertiesFilePath).getFile();
        //Load properties from classpath
        try {
            properties.load(new FileInputStream(filePath));
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public String getUsername() {
        return username;
    }

    public String getPassword() {
        return password;
    }

    public String getConnectionString() {
        return connectionString;
    }

    public Properties getProperties() {
        return properties;
    }
}

This is the test:

public class JdbcConnectionPropertiesTest {

    @Test
    public void testSetProperties(
//            @Mocked final Properties properties
    ) throws Exception {

        //Mock loadFilePath method so i dont end up mocking a ton of classes
        new 开发者_高级运维MockUp<JdbcConnectionProperties>() {
            @Mock
            void loadProperties(String propertiesFilePath) {
                //Doing nothing, simple "stub" method
            }
        };

        JdbcConnectionProperties jdbcConnectionProperties = new JdbcConnectionProperties("bla");
//        Deencapsulation.setField(jdbcConnectionProperties, "properties", properties);
//        Mockit.stubOutClass(JdbcConnectionProperties.class, "loadProperties");
        final String username = "username";
        final String password = "password";
        final String connectionType = "thin";
        final String serverAddress = "localhost";
        final String port = "1521";
        final String sid = "orcl";
        String connectionString = "jdbc:oracle:" + connectionType + ":@" + serverAddress + ":" + port + ":" + sid;

        new Expectations() {
            @Mocked
            Properties properties;

            {
                properties.get("user");
                result = username;

                properties.get("password");
                result = password;

                properties.get("connection_type");
                result = connectionType;

                properties.get("server_address");
                result = serverAddress;

                properties.get("port");
                result = port;

                properties.get("sid");
                result = sid;
            }
        };

        jdbcConnectionProperties.setProperties();

        Assert.assertEquals("Incorrect user", username, jdbcConnectionProperties.getUsername());
        Assert.assertEquals("Incorrect password", password, jdbcConnectionProperties.getPassword());
        Assert.assertEquals("Incorrect connection string", connectionString, jdbcConnectionProperties.getConnectionString());
    }
}

A couple of notes. I tried forsing the mocked properties into the object with Deencapsulation(i left them commented in the code).

I tried just mocking it with the @Mocked annotation.

I tried stubing it with stubOutClass.

This is not a first test i am writing, but im relativly new to JMockit. The tests i wrote before never caused me headaches like this one. I think i wrote about 20 - 30 tests with JMockit and never had problems like this.

The error is(in all the mentioned scenarios) :

java.lang.NullPointerException
    at java.util.Hashtable.get(Hashtable.java:335)
    at jdbc.JdbcConnectionPropertiesTest$2.<init>(JdbcConnectionPropertiesTest.java:49)
    at jdbc.JdbcConnectionPropertiesTest.testSetProperties(JdbcConnectionPropertiesTest.java:44)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:71)
    at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:199)
    at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:62)
    at com.intellij.rt.execution.application.AppMain.main(AppMain.java:120)

The class is very simple. The test should be very simple. But somehow the test crashes on the Expectations block(on the first properties expectation). If I comment the first ones, then it continues to throw it on next one. Tried any, anyString for argument matching.

The way I see it, i mock the JdbcConnectionProperties loadProperties so i can simplify my testing. Then i pass a mocked Properties object into the test.

And then...

...it should work. BTW, I never saw an exception of this magnitude in a Exceptions block.

Thank you.


Hashtable#get is one of a few methods not mocked by default by JMockit, because it can interfere with the JDK or with JMockit itself when mocked. You can get this particular test to work by explicitly asking for it to be mocked, with @Mocked("get").

It might be simpler to just use an actual ".properties" file in the test, though, with no mocking.


new Expectations() {
            @Mocked("getProperty")
            Properties properties;

            {
                properties.getProperty("user");
                result = username;

                properties.getProperty("password");
                result = password;

                properties.getProperty("connection_type");
                result = connectionType;

                properties.getProperty("server_address");
                result = serverAddress;

                properties.getProperty("port");
                result = port;

                properties.getProperty("sid");
                result = sid;
            }
        };

Thanks Rogerio. As he pointed out, the reason is the "internal" class mocking. A very small limitation to have in mind.

The other classes that require some attention are(i hope i can write this):

JMockit NullPointerException on Exceptions block?

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜