Testing a simple web app in Mule with JUnit

A simple JUnit test for when you just can’t remember the Mule JUnit testing syntax 😉

Mule flow
A Mule flow that takes a username as input and concatenates it with a “Hello”. The request is done by a GET call:

Flow code



    <http:listener-config 
       name="HTTP_Listener_Configuration" 
       host="0.0.0.0" 
       port="8081" 
       doc:name="HTTP Listener Configuration">
    
        <http:listener 
           config-ref="HTTP_Listener_Configuration" 
           path="/test" 
           doc:name="HTTP">
        <set-payload 
           value="#['Hello '+message.inboundProperties.'http.query.params'.username]" 
           doc:name="Set Payload">
    

Java test code:

import org.junit.Test;
import org.mule.DefaultMuleMessage;
import org.mule.api.MuleMessage;
import org.mule.api.client.MuleClient;
import org.mule.tck.junit4.FunctionalTestCase;

import junit.framework.Assert;

public class MyTests extends FunctionalTestCase {
	
	@Test
	public void testMyFlow() throws Exception {
        // Get the Mule Context
		MuleClient muleClient = muleContext.getClient();
		
        // Create an empty test Mule message
		DefaultMuleMessage message = 
                        new DefaultMuleMessage(null, muleContext);
		
        // Make a call to the tested web service
		MuleMessage responseMessage = muleClient.send(
                       "http://localhost:8081/test?username=Niklas", 
                       message
                    );
		
        // Get response as a string
		String responsePayload = responseMessage.getPayloadAsString();
		
        // Assert response
		Assert.assertEquals("Hello Niklas", responsePayload);
		
	}
	
	@Override
	protected String[] getConfigFiles() {
         // Path to the Mule configuration file that is being tested
		return new String[]{"src/main/app/helloworld.xml"};
	}

}

Tested on OSX 10.15.7, Mule 3.9.4, and JUnit 4.13

A simple chat application with javascript and ActiveMQ using STOMP messaging

Here is a small chat program that can be used for building a rich chat application, or if you just want a very simple chat program for your friends. It contains sending and receiving STOMP messages from an Apache ActiveMQ topic.

Prerequisites:
* Apace ActiveMQ server which can be found here: https://activemq.apache.org/components/classic/download/ Usually no configuration needed. Just start the server (./activemq start) and everything should work ok
* Stomp.js. A helper script for handling the WebSocket communication between ActiveMQ and your javascript application. This script can be found here, courtesy of Jeff Mesnil and Mark Broadbent: https://github.com/jmesnil/stomp-websocket/tree/master/lib

HTML:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>A simple ActiveMQ chat application</title>
    
    <script src="stomp.js"></script>
    <script src="index.js"></script>
</head>
<body>
    <textarea id="chat" rows="10" cols="35"></textarea>
    <br />
    <input id="message" size="40" type="text">
    <br />
    <button id="send" type="button" onclick="send()">Send</button>
</body>
</html>

Javascript:

// Setup websocket connection
const client = Stomp.client("ws://localhost:61614/stomp", "v11.stomp");
// Setup header options
const headers = {id: 'JUST.FCX', ack: 'client'};

// Connect to ActiveMQ (via websocket)
client.connect("admin", "admin", function () {
    // Setup subscription of topic (/topic/chat)
    client.subscribe("/topic/chat",
        function (message) {
            const msg = message.body;
            // Add message to textarea
            document.getElementById("chat").value += msg + "\n";
            // Acknowledge the message
            message.ack();
        }, headers);
});

function send() {
    const message = document.getElementById("message");
    // Send message to topic (/topic/chat)
    client.send("/topic/chat", {}, message.value);
    // Reset input field
    message.value = "";
}

Tested on OSX 10.15.7 and Apache ActiveMQ v5.16.3

MySQL Docker helper script

Here is a little script I made to help me start/stop and remove a MySQL docker instance. The script also points to an init file (docker-entrypoint-initdb.d) for the database where you can put all the creations of init objects needed, eg. CREATE TABLE…, INSERT INTO…, and so on

Usage:

>my-docker-db-script start # Starts MySQL docker instance. Creates it if it does not exist
>my-docker-db-script stop # Stops the MySQL docker instance
>my-docker-db-script remove # Removes the MySQL instance

Bash script:

#!/bin/bash

name="my-mysql-db"
command="$1"

function start() {
 state=$(2>/dev/null docker inspect $name --format '{{ .State.Status }}' || echo "")

 if [[ "$state" == "running" ]]; then
  echo "Databse already running!"
  exit 1
 fi
 
 if [[ "$state" == "exited" ]]; then
  echo "Database already exists. Starting..."
  docker start $name && echo "  ... database started"
 else
  echo "No database exists. Creating..."
  docker run -d -p 3306:3306 --name $name \
   -e MYSQL_ROOT_PASSWORD=root \
   -e MYSQL_DATABASE=my_db \
   -e MYSQL_USERNAME=myusername \
   -e MYSQL_PASSWORD=myuserpassword \
   -v $(pwd)/my-mysql-db/mysql-docker-init:/docker-entrypoint-initdb.d \
   -d mysql:5.6.51 && echo "  ... database created"
 fi

}

function stop() {
 state=$(2>/dev/null docker inspect $name --format '{{ .State.Status }}' || echo "")

 if [[ "$state" == "" ]]; then
  echo "Database does not exist!"
  exit 1
 fi

 echo "Stopping database ..."
 docker stop $name && echo "  ... database stopped"
}

function remove() {
 state=$(2>/dev/null docker inspect $name --format '{{ .State.Status }}' || echo "")

 if [[ "$state" == "" ]]; then
  echo "Database does not exist!"
  exit 1
 fi

 echo "Removing database"
 if [[ "$state" == "running" ]]; then
  docker stop $name && echo "  ...database stopped"
 fi

 docker rm $name && echo "   ...database removed"
}

case "$command" in
 start)
  start
  ;;
 stop)
  stop
  ;;
 remove)
  remove
  ;;
 *)
  echo "Invalid command: ${command}. Usage $0 (start|stop|remove)"
  exit 1
esac 

Tested on MySQL v5.6.51, OSX 10.15.7 and Docker Desktop 4.3.2