Tag Archives: unit testing

Unit Testing Using In-Memory MySQL Database On Spring

Well the title lied, there’s no such thing as in-memory MySQL database (or at least I won’t be using it for this article). Instead I will use H2 in-memory database setup to run in “MySQL mode”


  
  

(thanks to joensson for sharing this technique on SO)

If your app just uses plain jdbc then adding above datasource to your test context would be sufficient, but if you use JPA/Hibernate the cost of table setup, scanning etc could be quite significant.

To overcome this you can split the test context using y annotation.

In the example below I have unit tests for two DAOs: AccountDAOTest and CustomerDAOTest:

y({
  ation("/test-root-context.xml"),
  ation("AccountDAOTest-context.xml")
})
(SpringJUnit4ClassRunner.class)
public class AccountDAOTest {
}
y({
  ation("/test-root-context.xml"),
  ation("CustomerDAOTest-context.xml")
})
(SpringJUnit4ClassRunner.class)
public class CustomerDAOTest {
}

By doing this Spring test-root-context.xml will be setup once and reused accross all unit tests. Only put components common to all tests in test-root-context.xml. In my case I put the following:

  • DataSource
  • EntityManagerFactory
  • TransactionManager


  
  





  
  




  

All test specific components go into their respective context.

Don’t forget to add if your DAO uses it. This can’t be placed on test-root-context.xml because I don’t scan all my DAOs there.

And lastly — ofcourse — you need to make sure your pom.xml has dependency to spring-test, junit and h2



  com.h2database
  h2
  1.3.176
  test



  org.springframework
  spring-test
  ${org.springframework-version}
  test



  junit
  junit
  4.7
  test

Unit Testing Spring Bean Service With Mockito

The main idea of unit testing is quick compile-time checking that your code (somewhat) fulfills the business requirement.

A good unit testing practice is to not depend on any external system / dependencies. One way to substitute this external dependency is by using mocking tehcniques. Here I’ll go through unit testing a Spring bean service using .

Assuming you have a BankingService class that comes with a method to transfer money from one account to another. The method finds the Account object by its id using AccountsDAO repository class:


public class BankingService {

   private AccountsDAO accountsDAO;
  
  public void transfer(long fromAccountId, long toAccountId, double amount) throws Exception {
    Account fromAccount = accountsDAO.findById(fromAccountId);
    Account toAccount = accountsDAO.findById(toAccountId);
    
    fromAccount.setBalance(fromAccount.getBalance() - amount);
    toAccount.setBalance(toAccount.getBalance() + amount);
  }
}

AccountsDAO obtain the information from a persistent data store (most likely database), hence it is an external dependency. Here’s how to unit test this class:

  1. Ensure junit, spring-test and mockito dependencies are on the classpath
    
      junit
      junit
      4.7
      test
    
    
      org.springframework
      spring-test
      3.2.3.RELEASE
      test
    
    
      org.mockito
      mockito-core
      1.9.5
      test
    
    

  2. Setup BankingServiceTest.xml spring beans configuration file specific for our unit test. Note in here we created a mock AccountsDAO using Mockito. The order of mock creation here is important, if you place it at the bottom you will get autowiring error. I think this is because Spring couldn’t pre-determine the resulting type of the Mock object (it only looks as if it’s a org.mockito.Mockito bean type).
    
    
    
      
        
      
    
      
    
    
    

  3. Setup the unit test class. Notice the BankingService to test and the mock AccountsDAO are autowired into the unit test class
    (SpringJUnit4ClassRunner.class)
    ation("/BankingServiceTest.xml")
    public class BankingServiceTest {
    
       private BankingService bankingService;
       private AccountsDAO mockAccountsDAO;
      
      
      public void testTransfer() throws Exception {
        // Setup 2 accounts
        Account acc1 = new Account();
        acc1.setBalance(800.00);
        Account acc2 = new Account();
        acc2.setBalance(200.00);
        
        // Tell mock DAO to return above accounts when 1011 or 2041 is queried respectively
        when(mockAccountsDAO.findById(1011)).thenReturn(acc1);
        when(mockAccountsDAO.findById(2041)).thenReturn(acc2);
        
        // Invoke the method to test
        bankingService.transfer(1011, 2041, 500.00);
        
        // Verify the money has been transferred
        assertEquals(300.00, acc1.getBalance(), 0.001);
        assertEquals(700.00, acc2.getBalance(), 0.001);
      }
    }
    

  4. The when(..).thenReturn(..) syntax is where the magic happen. It will cause the mock object to return the Account we setup (as opposed of calling SQL to fetch it from database).

There are heaps more magic stuff you can do with Mockito. Checkout .

Source Code

Source code of this demo can be downloaded via git:

git clone https:///gerrytan/mycoolbank.git