www.mockcentral.org mockcentral on sourceforge.net

mockcentral: a jms example

This example use of MockCentral contains a test for a class that creates and sends a message to a jms Queue regarding a "total orders" value. The jms setup and actual message transmission is handled by a separate class (MessagePoster) and the value itself is obtained from an implementation of the OrderTotalProvider interface. The method we're testing (defined in the TotalOrdersMessageSender class) is as follows:

    (note: 'context' is a reference to a previously defined javax.naming.Context,
    and 'provider' is a reference to a previously defined OrderTotalProvider)
                
    public String sendTotalOrdersMessage() {
        String text = "total cumulative orders = " + provider.getTotalOrders();
        MessagePoster poster = new MessagePoster(context);
        return poster.sendMessage(text);
    }
       
The return value from this method is a String indicating the success status of the transmission, as illustrated by the sendMessage method from the MessagePoster class reprinted below:
    public String sendMessage(String text) {
        try {
            TextMessage message = queueSession.createTextMessage();
            message.setText(text);
            queueSender.send(message);
            return "message sent: " + text;
        }
        catch (Exception e) {
            return "unable to send message: " + text;
        }
    }
       
The relevant test case code (from the TotalOrdersMessageSenderTest class) is as follows:
      
    // create a new TotalOrdersMessageSender object
    TotalOrdersMessageSender sender =
        new TotalOrdersMessageSender(server.getContext());

    // assign the mock OrderTotalProvider implementation
    sender.setOrderTotalProvider((OrderTotalProvider) server.getProxy(
            "jms_example", "orderTotalProvider"));

    // load a fixture and test sending a message (when everything
    // should succeed)
    server.loadFixture("totalOrdersMessager_message_sent_ok");
    assertEquals(
        sender.sendTotalOrdersMessage(),
        "message sent: total cumulative orders = " + randomOrderTotal);

    // load a fixture and test sending a message (when an exception
    // should be thrown)
    server.loadFixture("totalOrdersMessager_message_sent_failed");
    assertEquals(
        sender.sendTotalOrdersMessage(),
        "unable to send message: total cumulative orders = "
            + randomOrderTotal);            
       
In the code above, the 'randomOrderTotal' value is an Integer created from a random number and supplied to the MockCentralServer.init method, as illustrated by this code from the test class's constructor:
    randomOrderTotal = new Integer((int) (Math.random() * 100));
    HashMap variablesMap = new HashMap();
    variablesMap.put("randomOrderTotal", randomOrderTotal);
    String path = getClass().getResource("jms_example.xml").getFile();
    server.init(variablesMap, path, true);
   

The full source code is supplied in the src/jms_example directory of the MockCentral Examples distribution (along with the xml configuration file and an ant build.xml file you can use to run the test and see the output).

discussion

To test the sendTotalOrdersMessage method, we need to create a Mock for the OrderTotalProvider interface and set up the MessagePoster class, which in turn requires creating mock objects for the following classes: QueueConnectionFactory, QueueConnection, QueueSession, Queue and QueueSender -- a tedious job made simple by using the MockCentralEditor. This example illustrates how to use a mock object obtained from the server in an assignment for an interface implementation (the mock OrderTotalProvider) and how to use the javax.naming.Context built in to the MockCentralServer as a quasi-mock object itself. It also shows the power of using multiple fixtures (and loading them on the fly in a test case) to change the expected behaviour feeding the test: in this instance, we wanted an exception to be thrown by the QueueSender and subsequently caught by the LogEntrySender.sendMessage method in order to test the exception-handling code. While defining full sets of the jms-related mock objects for two different fixtures might seem like a lot of work, using the MockCentralEditor's copy and paste functions makes it quick and easy, and setting up a "parallel" fixture simple. Another feature illustrated by this example is the use of a "variable" object (supplied to the server's init method) for a component of a mock object method -- in this example (which is purely for illustration), the random number generated in the test class's constructor is used for the return value for the OrderTotalProvider.getTotalOrders method.

back to examples