String Reversing in Scala

Playing around today with Scala I’ve created this construct to reverse a string in other than the obvious:

scala> "hello".reverse
res62: String = olleh

that is:

scala> "hello".foldLeft(List[Char]()){(a,b)=>b::a}.mkString("")
res61: String = olleh

breaking it down initially we have the string literal:

scala> "hello"
res1: java.lang.String = hello

then we apply on that literal the foldLeft operation building up on a List of chars:

scala> "hello".foldLeft(List[Char]()){(a,b)=>b::a}
res0: List[Char] = List(o, l, l, e, h)

and finally call the mkString(“”) method on the above to compile a string:

scala> "hello".foldLeft(List[Char]()){(a,b)=>b::a}.mkString("")
res0: String = olleh

By Dimi Posted in Scala

JUnit 4 Showcase – Parameterized Tests

A very interesting feature is the usage of parameterized tests to save us of the trouble of repetitive test code and automatically call test cases using predefined collection of test data.

Everything starts with the @RunWith(Parameterized.class) annotation that needs to be applied on the test class this time. A special public static method annotated as @Parameters signals the collection of test data. This set will be called by JUnit behind the scenes once per each data set calling the constructor for the creation of a new test class. The constructor should allocate this collection of test data into encapsulated members. These members would be used by the @Test annotated methods performing the test cases.

An example would look like this:

package com.dimitrisli.junitshowcase.parameterizedTest;

import java.util.Arrays;
import java.util.Collection;

import junit.framework.Assert;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import org.junit.runners.Parameterized.Parameters;



@RunWith(Parameterized.class)
public class ParameterizedTesting {

	@Parameters
	public static Collection<?> data(){
		return Arrays.asList(new Object[][]{
				{2,3,6},
				{3,4,12},
				{4,5,20},
				{5,6,30},
				{6,7,42}
		});
	}
	
	private int a;
	private int b;
	private int result;
	
	public ParameterizedTesting(int a, int b, int result){
		this.a = a;
		this.b = b;
		this.result = result;
	}
	
	@Test
	public void multiplicationCalculation(){
		int calcResult = a*b;
		System.out.println("a="+a+", b="+b+". Expected result= "+result+", and calculated result= "+calcResult);
		Assert.assertEquals(result, calcResult);
	}
	
}

that yields back the result:

a=2, b=3. Expected result= 6, and calculated result= 6
a=3, b=4. Expected result= 12, and calculated result= 12
a=4, b=5. Expected result= 20, and calculated result= 20
a=5, b=6. Expected result= 30, and calculated result= 30
a=6, b=7. Expected result= 42, and calculated result= 42

This code can be found in this Github repository.

JUnit 4 Showcase – testing exceptions

A nice way to determine we are expecting an exception during a test case is to use the @Test annotation with the expected parameter.

A trivial example would look like so:

package com.dimitrisli.junitshowcase.exceptionTesting;

import org.junit.Test;

public class ExceptionsTesting {

	@Test(expected = NullPointerException.class)
	public void method(){
		throw new NullPointerException();
	}

	@Test(expected = IllegalArgumentException.class)
	public void method2(){
		throw new IllegalArgumentException();
	}
}

This code extract along with the other examples of the JUnit 4 Showcase can be found in this Github repository.

JUnit 4 Showcase – Using timeouts

An interesting way to performance test the time it takes for an expensive operation to complete is to use JUnit 4’s timeouts. This way we can capture poor response times. In this case the test case fails if it takes longer than the predefined time in milliseconds to complete.

A trivial example would look like this:

package com.dimitrisli.junitshowcase.performanceTesting;

import org.junit.Test;

import junit.framework.Assert;

public class PerformanceTest {

	@Test(timeout=100)
	public void method(){
		Assert.assertTrue(true);
	}
}

This code extract along with the full JUnit 4 showcase can be found in this Github repository.

JUnit 4 Showcase – Setting up and optimising unit tests

JUnit 4 has been a major rewrite of the JUnit API mainly:

  • it uses annotations
  • a test can be any POJO class, no need to extend TestCase or have special name conventions for test classes and methods. Although the main rules remain that each JUnit method needs to be public void and have no arguments.

In case we want to run initialisation code prior and post each test case (JUnit method) we can use the @Before and @After annotations saving us from the trouble of initialising the same code in each test case.

Similarly, if we need to run initialisation code prior and post every test class this time we can use the @BeforeClass and @AfterClass annotation. Other than these annotations, these particular methods need to be static.

Having as an example the following code:

package com.dimitrisli.junitshowcase.beforeAfter;

import org.junit.After;
import org.junit.AfterClass;
import org.junit.Assert;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;


public class BeforeAfterTest {

	@BeforeClass
	public static void initialiseClass(){
		System.out.println("init class");
	}
	
	@Before
	public void initialiseTest(){
		System.out.println("init test");
	}
	
	@Test
	public void test1(){
		System.out.println("inside test1");
		Assert.assertTrue(true);
	}

	@Test
	public void test2(){
		System.out.println("inside test2");
		Assert.assertTrue(true);
	}
	
	@After
	public void teardownTest(){
		System.out.println("teardown test");
	}
	
	@AfterClass
	public static void teardownClass(){
		System.out.println("teardown class");
	}
}

produces the output:

init class
init test
inside test1
teardown test
init test
inside test2
teardown test
teardown class

The code can be found in this Github repository.

Sending Gmail from Spring

Here’s a working example of how to send an Email (customised for the Gmail client) from a Spring application.

The POM would look like this:

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <groupId>com.dimitrisli</groupId>
  <artifactId>springEmail</artifactId>
  <version>0.0.1-SNAPSHOT</version>
  <properties>
  	<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
  </properties>
  <dependencies>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-context</artifactId>
      <version>3.0.6.RELEASE</version>
      <scope>compile</scope>
    </dependency>
    <dependency>
    	<groupId>org.springframework</groupId>
    	<artifactId>spring-support</artifactId>
    	<version>2.0.8</version>
    </dependency>
    <dependency>
    	<groupId>com.sun.mail</groupId>
    	<artifactId>javax.mail</artifactId>
    	<version>1.4.4</version>
    </dependency>
  </dependencies>
  <build>
  	<plugins>
  		<plugin>
  			<artifactId>maven-compiler-plugin</artifactId>
  			<configuration>
  				<source>1.6</source>
  				<target>1.6</target>
  			</configuration>
  		</plugin>
  	</plugins>
  </build>
</project>

Few things to notice on this POM:

  • Specifying UTF-8 platform agnostic source encoding. If this property is not there Maven would complain about system specific encoding.
  • Due to the dependency tree, specifying spring-context is enough to bring the minimal number of Spring related jars that are needed to construct the minimal Spring project that uses the ApplicationContext, therefore Maven saves us from this trouble. Namely, the jars that are absolutely necessary:
    • spring-context
    • spring-beans
    • spring-core
    • spring-expression
    • spring-asm
    • commons-logging
  • Since we would be using Spring’s SimpleMailMessage the jar spring-support is also needed.
  • Also the javax.mail is needed for the despatching of the email.
  • Explicitly specifying java 1.6 for compilation using the maven maven-compiler-plugin plugin.

Our service layer is represented from the following class:

package com.dimitrisli.springEmail;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.mail.MailSender;
import org.springframework.mail.SimpleMailMessage;
import org.springframework.stereotype.Service;

@Service("emailService")
public class EmailService {

	@Autowired
	private MailSender emailSender;
	@Autowired
	private SimpleMailMessage exceptionEmail;

	public void sendEmail(String from, String to, String subj, String body){
		SimpleMailMessage message = new SimpleMailMessage();
		message.setFrom(from);
		message.setTo(to);
		message.setSubject(subj);
		message.setText(body);
		emailSender.send(message);
	}

	public void sendExceptionEmail(String error){
		SimpleMailMessage exceptionEmailMessage = new SimpleMailMessage(exceptionEmail);
		exceptionEmailMessage.setText(error);
		emailSender.send(exceptionEmailMessage);
	}
}

Few things to notice:

  • @Service Spring annotation is another way of saying @Component but has a better representation of the service layer. Also specifying the bean id at that stage in the java bean makes the bean reference in an xml  configuration file unnecessary.
  • @Autowired is taking care of injecting the dependencies of the emailSender and exceptionEmail functionality. Loose coupling at its best.

Under /src/main/resources we store the Spring configuration file:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:context="http://www.springframework.org/schema/context"
    xsi:schemaLocation="
            http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
            http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd"
>
	<!--context namespace and schema for the component-scan to work-->
	<context:component-scan base-package="com.dimitrisli.springEmail" />

	<bean id="emailSender" class="org.springframework.mail.javamail.JavaMailSenderImpl">
		<property name="host" value="smtp.gmail.com"/>
		<property name="port" value="25"/>
		<property name="username" value="your@gmailhere.com"/>
		<property name="password" value="yourpass"/>
		<property name="javaMailProperties">
			<props>
				<prop key="mail.transport.protocol">smtp</prop>
				<prop key="mail.smtp.auth">true</prop>
				<prop key="mail.smtp.starttls.enable">true</prop>
				<prop key="mail.debug">true</prop>
			</props>
		</property>
	</bean>

	<bean id="exceptionEmail" class="org.springframework.mail.SimpleMailMessage">
		<property name="from">
			<value>from@email.com</value>
		</property>
		<property name="to">
			<value>to@email.com</value>
		</property>
		<property name="subject" value="Something went wrong please investigate"/>
	</bean>

</beans>

Things to notice:

  • Namespaces include the beans reference due to the tags we are using and the context reference due to the component-scan
  • component-scan on the specified package is activating the @Autowired magic.
  • The emailSender bean is tailored for the Gmail specific settings passing all the needed parameters to the JavaMailSenderImpl.
  • The exceptionEmail bean is following another technique having a preconfigured SimpleMailMessage.

Finally the MainSpringContainer which is laying down the two test scenarios creating a Spring Application Context:

package com.dimitrisli.springEmail;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.FileSystemXmlApplicationContext;

public class MainSpringContainer {

	public static void main(String[] args) {
		ApplicationContext context = new FileSystemXmlApplicationContext("/src/main/resources/spring.xml");
		EmailService emailService = (EmailService) context.getBean("emailService");
		emailService.sendEmail("from@email.com", "to@email.com", "test subject", "test body");
		emailService.sendExceptionEmail("something went terribly wrong");
	}
}

You can find the code in this Github repo