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.