July 17, 2015

Getting Started with Mockito

Introduction

To create effective unit test, they should be fast. But also you might need to mock object out to be able to write unit tests. The most common library to use for mocking is mockito.

Example: Mock expected results

import static org.hamcrest.CoreMatchers.*;
import static org.junit.Assert.*;
import static org.mockito.Matchers.*;
import static org.mockito.Mockito.*;
...
    @Test
    public void testIterator() throws Exception {
        Iterator mock = mock(Iterator.class);
        when(mock.next()).thenReturn("Hello").thenReturn("World");
        assertThat("Hello World", is(equalTo(mock.next() + " " + mock.next())));
    }

Example: Mock expected result with input

import static org.hamcrest.CoreMatchers.*;
import static org.junit.Assert.*;
import static org.mockito.Matchers.*;
import static org.mockito.Mockito.*;
...
    @Test
    public void testArrayList() throws Exception {
        ArrayList mock = mock(ArrayList.class);
        when(mock.get(1)).thenReturn("Foo");
        assertThat("Foo", is(equalTo(mock.get(1))));
    }

Example: Mock expected results with any input

import static org.hamcrest.CoreMatchers.*;
import static org.junit.Assert.*;
import static org.mockito.Matchers.*;
import static org.mockito.Mockito.*;
...
    @Test
    public void testArrayListAny() throws Exception {
        ArrayList mock = mock(ArrayList.class);
        when(mock.get(anyInt())).thenReturn("Foo");
        assertThat("Foo", is(equalTo(mock.get(1))));
    }

Example: Mock and expect exception

import static org.hamcrest.CoreMatchers.*;
import static org.junit.Assert.*;
import static org.mockito.Matchers.*;
import static org.mockito.Mockito.*;
...
    @Test(expected = IOException.class)
    public void testOutputStream() throws Exception {
        OutputStream mock = mock(OutputStream.class);
        doThrow(new IOException()).when(mock).close();
        mock.close();
    }

Example: Mock and verify that metods were invoked

import static org.hamcrest.CoreMatchers.*;
import static org.junit.Assert.*;
import static org.mockito.Matchers.*;
import static org.mockito.Mockito.*;
...
    @Test
    public void testOutputStreamVerify() throws Exception {
        OutputStream mock = mock(OutputStream.class);
        BufferedOutputStream fos = new BufferedOutputStream(mock);
        fos.close();
        verify(mock).close();
    }

Using Hamcrest with JUnit 4

Introduction

The latest JUnit 4 comes with a transitive dependency of hamcrest. What hamcrest brings to the table is to increase the readability of the test code. This is important because codes are often more read than written.

Example

@Test
public void testEqualTo() throws Exception {
    assertThat(Foo.hello(), is(equalTo("Hello World")));
}

Core

The starting point is org.junit.Assert.assertThat(T actual, Matcher matcher) and the matcher methods in org.hamcrest.CoreMatchers.*:

  • allOf()
  • any()
  • anyOf()
  • anything()
  • describedAs()
  • equalTo()
  • instanceOf()
  • is()
  • not()
  • notNullValue()
  • nullValue()
  • sameInstance()

allOf()

allOf() is a simple assertion that just says all of the matcher arguments must be true.

@Test
public void testAllOf() throws Exception {
    assertThat(Foo.hello(), is(allOf(notNullValue(), instanceOf(String.class), equalTo("Hello World"))));
}

any()

This matcher just checks that the actual result is a class of a certain type.

@Test
public void testAny() throws Exception {
    assertThat(Foo.hello(), is(any(String.class)));
}

anyOf()

If any of the matchers are true this assertion will pass.

@Test
public void testAnyOf() throws Exception {
    assertThat(Foo.hello(), is(anyOf(nullValue(), instanceOf(String.class), equalTo("Goodbye"))));
}

anything()

This matcher will always evaluates to true.

describedAs()

This allows you to override the default description for a matcher.

equalTo()

See above.

instanceOf()

Checks that you have an instance of a particular type.

is()

See above.

not()

Just reverses the outcome of a matcher.

@Test
public void testNot() throws Exception {
    assertThat(Foo.hello(), is(not("Bar")));
}

notNullValue()

Simply does a null check

nullValue()

Assert a null value.

sameInstance()

Assert two Objects are ==, i.e. NOT equals()

@Test
public void testSameInstance() throws Exception {
    assertThat(2 + 2, is(sameInstance(4)));
    assertThat(new Integer(2 + 2), is(not(sameInstance(new Integer(4)))));
}

JUnit testing CDI and EJB with Mockito, OpenEJB and Arquillian

Introduction

Unit testing EE have previously been hard, but since EE 6 and onward the EE specification has been improved on the test front.

Since EE 6 the following has been added:

  • javax.ejb.embeddable.EJBContainer – A standardized test container for EJB.
  • Portable JNDISyntax – Now all EE container must conform to the same JNDI registration and lookup name spaces. Before EE 6, there was no name standard and each EE container had each different name standard.

Do we need CDI and EJB injection for unit testing?

The general rule of thumb is to make unit tests fast, because if they are not, people will starts to disable test cases. And this will make unit tests contra productive.

Loading a CDI or EJB container takes time. Which is also true for Spring Application Context. So try to write your unit test without the need to load some kind of container.

JPA and JDBC can be tested with standard Java SE

See http://magnus-k-karlsson.blogspot.se/2015/02/hibernate-best-practise-jpa-20-and.html.

Logic and EJB can be tested with Mockito

When testing logic or EJB there is in most cases no need to create a EJB context. Try to use mockito, to mock your surroundings.

EJB Container Unit Testing

In some cases there is actually a need to create an EJB context. The two most common solutions are:

  • OpenEJB
  • Arquillian

OpenEJB

Pros:

  • Is faster to start and stop than Arquillian
  • More easier to learn
  • Easy to use maven dependency

Cons:

  • Only support standard EE (which is also a pro, since then you know your code will run in any EE container.).
  • Does not support mere CDI, must use first an EJB to test pure CDI functionality. Can put EJB in test directory.

See

Arquillian

Pros:

  • Can test EE container specific code.
  • Support test of pure CDI code.

Cons:

  • Is slower than OpenEJB.
  • Its maven dependencies are long and complex.
  • Is harder to learn compared with OpenEJB.

See:

July 15, 2015

Why EJB?

Introduction

When people think of Java EE, they think in first hand of EJB, even though the EE specification contains much than EJB. For example Rod Johnson (founder of Spring) pointed out in the Expert One-on-One J2EE Development without EJB that JDBC, JTA and JMS are successful parts of EE.

But a lot has happen when this book was written and recent EE version starting with 5, but especially 6 and 7 had made EE development even easier than Spring development.

So if you are thinking of choosing EE, you might wonder what EJB contributes with:

  1. Pooling
  2. Transaction
  3. Security
  4. Monitoring and Management
  5. Asynchronous

Pooling

This makes accessing a EJB faster. Typically usage with Spring is to lazy inject things when a Business Object is requested.

Pooling is also a DOS protection since you cannot request endless number of Business Object. When the pool is empty of non busy EJB, the request will fail fast. This handling is important, since accepting new request when the server is overloaded will only worsen the situation.

Further sizing and resizing the pool and other pool is typically something a application administrator want to do after the deployment in production and this is done from unified interface in the EE container. No need to go in each application and know its inner configuration.

Transaction

Every public method will default start a new transaction if no one exists.

Security

The EE specification contains a good security API and is easy to use and covers all the EE components.

Since the EE 6 the EAR archive is history. Now EJB can be bundle in standard WAR archive.

And standard web.xml security is quite straight forward.

Monitoring and Management

With the emerge of DevOps (Development Operation) the monitoring and management has grown in importance (even though it always has been important).

All modern EE container has today this capability of monitoring and manage EJB as a standard.

Asynchronous

javax.ejb.Asynchronous was introduced in EE 6 and is easy to use. Example to make a method asynchronous:

@Stateless
public class OrderProcessorBean {

    // synchronous method
    public boolean validate(Order order) throws PaymentException {
        ...
    }

    @Asynchronous
    public Future<string> processPayment(Order order) throws PaymentException {
        ...
    }
}