Friday, May 28, 2010

EasyMock your Jms Listener

EasyMock as the name states "Its an easy to Mock framework" that mocks interfaces to do better unit testing. I tried some samples and found it really amazing, and thought of creating a sample that helps to understand mocking better.

Assume
JMSListener is a business class that listens to a JMS Queue and does some business processing based on the received message. The problem with such components are they are dependent on some resources external (J2ee Container, Queue, database, LDAP etc.) to the code itself. This makes unit testing difficult and puts the EasyMock on driving seat :).

package com.jms;

import javax.jms.JMSException;
import javax.jms.Message;
import javax.jms.MessageListener;
import javax.jms.TextMessage;

public class JMSListener implements MessageListener{
public void onMessage(Message arg0) {
TextMessage msg = (TextMessage)arg0;
try {
//Some Mission Critical Logic :)
System.out.println("Got the message.. \n"+msg.getText());
} catch (JMSException e) {
e.printStackTrace();
}
}
}


Let's see the Unit Test and how EasyMock Mocks the Message interface, The highlighted lines shows the Magic of EasyMock & power of interfaces...

package com.jms;

import static org.easymock.EasyMock.*;
import javax.jms.JMSException;
import javax.jms.TextMessage;
import junit.framework.TestCase;

public class JMSListenerTest extends TestCase {
private TextMessage mock;
private JMSListener listener;

protected void setUp() {
mock = createMock(TextMessage.class);
listener = new JMSListener();
}

public void testRemoveNonExistingDocument() throws JMSException {
expect(mock.getText()).andReturn("content");
replay(mock);
listener.onMessage(mock);
verify(mock);
}
}

Reference
http://easymock.org/EasyMock2_2_Documentation.html