Tag Archives: JUnit

Mockito & Co!

It’s been a while I didn’t post anything…

Today I’m back with Mockito 🙂
I played with it on my project and I learn some stuff… Ok, it’s mainly because I had some errors in my tests but still…
It’s always good to share even if I am the only one who use this samples!

I don’t want to present what is Mockito, use Google for that purpose!
I just want to share how I use it in my projects, I you may know, Mockito is very helpful when you need to test a particular component without using the whole application, it is useful for unit testing but even for integration tests when you do not have access to all external APIs for example.
The simplest way to use it is to replace the real implementation by the mock and then you can instruct him how he should behave in your test, here’s a simple example with a (Spring) repository who should return a bunch of data:

Mockito.when(promoterRepository.getPromoters(anyString(), anyBoolean(), anyBoolean(),  anyBoolean()))
    .thenReturn(buildFakePromoters());

Here, we have a promoterRepository (injected thanks to Spring) and we teach it to return a list of fake objects, this is probably the simplest way to do it.

But sometime, you receive an error telling that Mockito cannot call do what you asked for (WrongTypeOfReturnValue)… But what’s the hell?
In that case, you can refactor your test this way:

Mockito.doReturn(buildFakePromoters())
    .when(promoterRepository).getPromoters(anyString(), anyBoolean(), anyBoolean(), anyBoolean());

Almost the same but for some obscure reason, it solves the error.

In the 2 examples above, the mock is always returning the same object, sometime, you want your mock to return different instances, or at least call the method each time (I had this issue when I was working on tests involving cache), in that particular case, you can write the test that way:

Mockito.when(promoterRepository.getPromoters(anyString(), anyBoolean(), anyBoolean(), anyBoolean()))
	.thenAnswer(new Answer() {
		@Override
		public Promoter answer(final InvocationOnMock invocation) throws Throwable {
			return buildFakePromoters();
		}
	});

In some cases, you may need to check how many times a method is called, then Mockito can also help on this:

Mockito.doReturn(buildFakePromoters())
    .when(promoterRepository).getPromoters(anyString(), anyBoolean(), anyBoolean(), anyBoolean());

Collection promoters = promoterService.findPromoters();
//normally, the method should have been called once
verify(promoterRepository, times(1)).getPromoters(anyString(), anyBoolean(), anyBoolean(), anyBoolean());

Mockito is simply amazing 😀

Add datasource access in tests

In my web applications, the datasource is often defined in Tomcat (see here), when I execute my integration tests using JUnit, I don’t need Tomcat, but I need an access to the database, and to the Spring context too.
My solution is to create an abstract test which provides me these features, I use:

Doing this, there’s nothing to change in the class I test, I can check the database access, the transaction management or the bean definitions:

package net.classnotfound;
import java.sql.SQLException;
import javax.naming.NamingException;
import oracle.jdbc.pool.OracleDataSource;

import org.junit.BeforeClass;
import org.junit.runner.RunWith;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.mock.jndi.SimpleNamingContextBuilder;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations={"/integrationTestContext.xml"})
public abstract class AbstractTest {
    
    private static final String PWD = "password";
    private static final String USER = "user";
    private static final String JDBC_URL = "jdbc:oracle:thin:@localhost:1521:classnotfound";
    private static final Logger LOG = LoggerFactory.getLogger(AbstractTest.class); 

    @BeforeClass
    public static void setUpClass() throws Exception {

        OracleDataSource ods = null;
        try {
            ods = new OracleDataSource();
        } catch (SQLException e) {
            LOG.error(null,e);
        }
        ods.setURL(JDBC_URL);
        ods.setUser(USER);
        ods.setPassword(PWD);
        LOG.info("DB connection, URL: {}; user: {}; pwd {}", new String[] {JDBC_URL, USER, PWD});

        SimpleNamingContextBuilder builder = null;
        try {
            builder = SimpleNamingContextBuilder.emptyActivatedContextBuilder();
            builder.bind("java:comp/env/jdbc/applicationDatasource",ods);
        } catch (NamingException e) {
            LOG.error(null,e);
        }
    }
}

And to use it in my test, I just need to extend this class:

public class TestService extends AbstractTest{

    @Autowired
    private MyService myService;
...
}