The major thing the code lacked was a proper unit test with coverage higher than 80%, well it didn't have a unit test at all.
Adding a unit test normally is not a big deal, but in this case, the class, a simple servlet that connects to a remote RMI object and calls a status method on it, directly uses
java.rmi.Naming
.java.rmi.Naming
is notorious for its static methods, which are hard to mock when unit testing.There are great products out there, like powermock that can actually mock static methods, but not in system classes.
I could change the servlet code and provide a wrapper around accessing the
java.rmi.Naming
class, but I didn't want to change the code.Instead I chose to not mock
java.rmi.Naming
, but instead just create my own instance:@BeforeClassThis registry is alive and kickin' during the execution of my test suite, so I can now register the mock object that implements the remote business interface:
public static void initNamingRegistry() throws RemoteException {
// Create a local registry with an arbitrary port number
rmiRegistry = LocateRegistry.createRegistry(9901);
@BeforeThen the actual servlet method can bet tested:
public void registerRemoteMock() throws Exception {
// Register the mock of the remote business object
rmiRegistry.bind("testName", remoteMock);
}
@TestNice, clean and simple!
public void testSomeBehaviour()
// Prepare the mocks
when(requestMock.getParameter("name").thenReturn("val");
...
// Call the test method
testObject.doGet(requestMock, responseMock);
// Verify the calls if needed
verify(remoteMock).doIt();