Unit testing code that sends JMS messages
Asked Answered
M

5

6

I have a class that after it does some stuff, sends a JMS message. I'd like to unit test the "stuff", but not necessarily the sending of the message.

When I run my test, the "stuff" green bars, but then fails when sending the message (it should, the app server is not running). What is the best way to do this, is it to mock the message queue, if so, how is that done.

I am using Spring, and "jmsTemplate" is injected, along with "queue".

Mariahmariam answered 2/12, 2008 at 22:1 Comment(1)
I just added the java tag, if that's not right you can remove it.Stillwell
B
8

The simplest answer I would use is to stub out the message sending functionality. For example, if you have this:

public class SomeClass {
    public void doit() {
        //do some stuff
        sendMessage( /*some parameters*/);
    }

    public void sendMessage( /*some parameters*/ ) { 
        //jms stuff
    }
}

Then I would write a test that obscures the sendMessage behavior. For example:

@Test
public void testRealWorkWithoutSendingMessage() {
    SomeClass thing = new SomeClass() {
        @Override
        public void sendMessage( /*some parameters*/ ) { /*do nothing*/ }
    }

    thing.doit();
    assertThat( "Good stuff happened", x, is( y ) );
}

If the amount of code that is stubbed out or obscured is substantial, I would not use an anonymous inner class but just a "normal" inner class.

Bernie answered 2/12, 2008 at 22:10 Comment(0)
H
6

You can inject a mocked jmsTemplate.

Assuming easymock, something like

JmsTemplate mockTemplate = createMock(JmsTemplate.class)

That would do the trick.

Hasa answered 2/12, 2008 at 22:9 Comment(2)
Calling EasyMock.createMock(JmsTemplate.class) gets me a java.lang.NoClassDefFoundError: javax/jms/JMSException. Any suggestions?Ely
@Ely Have you got something like javax.jms-api jar in your classpath?Hasa
H
1

Another option is MockRunner which provides mock environments for JDBC, JMS, JSP, JCA and EJB. This allows you to define the queues/topics just like you would in the "real" case and simply send the message.

Harlamert answered 3/12, 2008 at 8:56 Comment(0)
R
1

Regarding how to organise all those test stubbing / mocks in a larger application...

We build and maintain a larger Enterprise App, which is configured with Spring. The real App runs as EAR on a JBoss Appserver. We defined our Spring context(s) with a beanRefFactory.xml

<bean id="TheMegaContext"
          class="org.springframework.context.support.ClassPathXmlApplicationContext">
    <constructor-arg>
        <list>
            <value>BasicServices.xml</value>
            <value>DataAccessBeans.xml</value>
            <value>LoginBeans.xml</value>
            <value>BussinessServices.xml</value>
            ....
        </list>
    </constructor-arg>
</bean>

For running the unit tests, we just use a different beanRefFactory.xml, which exchanges the BasicServices to use a test version. Within that test version, we can define beans with the same names as in the production version, but with a mock/stub or whatever implementation (e.g. database uses a local Apache DPCP pooled datasource, while the production version uses the data source from the Appserver).

Rasping answered 30/11, 2010 at 15:34 Comment(0)
C
0

This is the perfect candidate to use jMock unit testing since your server is not running but you would use jMock to simulate interaction with the server.

Counterglow answered 17/1, 2012 at 7:22 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.