Tag Archives: Software testing

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

Mock a dependency in system under test in a Spring Boot application with Mockito

System under test class example:

import my.special.sclient
...

class App {
  Sclient sclient = getNewSclient();
  
  public String methodA(String input) { 
    return sclient.getValue(input);
  }

  protected Sclient getNewSclient() {
    return new Sclient();
  }
}

Test class example:

import org.mockito.InjectMocks;
import org.mockito.Spy;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;

import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Test;
...

class Test {
  @Spy
  @InjectMocks
  private App sut;

  @Mock
  Sclient mockClient;

  @BeforeMethod
  public void setUp() {
    MockitoAnnotations.initMocks(this);
    when(sut.getNewSclient()).thenReturn(mockClient);
    when(mockClient.getValue("bar")).thenReturn("foo");
  }

  @Test
  public void myTest() {
    String value = sut.getValue("bar");
    assertThat(value, is("foo"));
  }
}

So, how does this work? I will try to explain below:

1. First we need to be able to intercept the ‘sclient’ in the App class. This is done by simply creating a ‘getNewSclient()’ function and then mock it in the Test class so that we instead can use a mocked version of it.

2. Next we need to setup our test class. Here we need both a @Spy and @InjectMocks on the App object. We also need a mocked instance of the ‘sclient’ we are going to use

3. Now we need to set upp the desired behaviour of our mocked ‘sclient’. We set it so that if you input “bar” you should get “foo” back

4. Done!

Tested on Java v1.8.0_252, Mockito v3.3.3, TestNG v6.11 and Spring Boot v2.2.4

Read the application log when testing your Spring application

From time to time I need to check so that a function correctly logs error messages to the application log. Here is one solution using Logback in a Spring application

import ch.qos.logback.classic.Logger;
import ch.qos.logback.classic.spi.LoggingEvent;
import ch.qos.logback.core.Appender;

import org.mockito.ArgumentMatcher;

import org.slf4j.LoggerFactory;

import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;

@Test
public void shouldWriteErrorMessageToLog() {
  Logger l = (Logger) LoggerFactory.getLogger(Logger.ROOT_LOGGER_NAME);
  Appender mockAppender = mock(Appender.class);
  l.addAppender(mockAppender);

  /*
   * Call function that is expected to write to the application log
   */

  verify(mockAppender).doAppend(argThat(new ArgumentMatcher() {
    @Override
    public boolean matches(final Object argument) {
      return ((LoggingEvent)argument).getMessage().contains("FooBar");
    }
  }));
}

Tested with Spring Boot v2.2.4 and TestNG v6.11