This example shows how to write junit to test Spring RowMapper functionality while mocking JdbcTemplate with Mockito.
This also increases code coverage of RowMapper code.
Below is the DAO class that returns list of users with RowMapper using Lambdas.
Spring JdbcTemplate RowMapper Example with Lambdas
package com.kswaughs.dao; import java.sql.ResultSet; import java.util.List; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.stereotype.Repository; import com.kswaughs.beans.User; @Repository public class UserDAO { @Autowired private JdbcTemplate jdbcTemplate; public List<User> getAllUsers() { return jdbcTemplate.query("SELECT ID, NAME, STATUS FROM USER", (ResultSet rs, int rowNum) -> { User user = new User(); user.setId(rs.getInt("ID")); user.setName(rs.getString("NAME")); user.setStatus(rs.getBoolean("STATUS")); return user; }); } }
Below is the Junit test class to test RowMapper code by mocking JdbcTemplate to return two rows.
Spring JdbcTemplate RowMapper Junit test example
package com.kswaughs.dao; import java.sql.ResultSet; import java.util.ArrayList; import java.util.List; import org.junit.Assert; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.ArgumentMatchers; import org.mockito.InjectMocks; import org.mockito.Mock; import org.mockito.Mockito; import org.mockito.junit.MockitoJUnitRunner; import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.jdbc.core.RowMapper; import com.kswaughs.beans.User; @RunWith(MockitoJUnitRunner.class) public class UserDAOTest { @Mock private JdbcTemplate jdbcTemplate; @InjectMocks private UserDAO userDAO; @SuppressWarnings("unchecked") @Test public void testGetAllUsers() { Mockito.when(jdbcTemplate.query( ArgumentMatchers.anyString(), ArgumentMatchers.any(RowMapper.class))) .thenAnswer((invocation) -> { RowMapper<User> rowMapper = (RowMapper<User>) invocation.getArgument(1); ResultSet rs = Mockito.mock(ResultSet.class); // Mock ResultSet to return two rows. Mockito.when(rs.getInt(ArgumentMatchers.eq("ID"))) .thenReturn(506, 400); Mockito.when(rs.getString(ArgumentMatchers.eq("NAME"))) .thenReturn("Jim Carrey", "John Travolta"); Mockito.when(rs.getBoolean(ArgumentMatchers.eq("STATUS"))) .thenReturn(true, false); List<User> users = new ArrayList<>(); users.add(rowMapper.mapRow(rs, 0)); users.add(rowMapper.mapRow(rs, 1)); return users; }); List<User> users = userDAO.getAllUsers(); // Assert First Row assertFirstUser(users.get(0)); // Assert Second Row assertSecondUser(users.get(1)); } public void assertFirstUser(User user) { Assert.assertEquals(Integer.valueOf(506), user.getId()); Assert.assertEquals("Jim Carrey", user.getName()); Assert.assertTrue(user.isStatus()); } public void assertSecondUser(User user) { Assert.assertEquals(Integer.valueOf(400), user.getId()); Assert.assertEquals("John Travolta", user.getName()); Assert.assertFalse(user.isStatus()); } }
Thanks! By the way, ArgumentMatchers.eq() not needed inside the Mockito.when(), when returning ResultSet rows. Can just pass the columnLabel directly.
ReplyDeleteAlso `RowMapper rowMapper = (RowMapper) invocation.getArgument(1);` doesn't need to be casted. I think this was the only "generic" line for me so after getting rid of casting, could also get rid of the `@SuppressWarnings("unchecked")` annotation too
This worked perfectly for me
ReplyDeleteThank you very much!!!
ReplyDeleteThank you very much!!
ReplyDeleteShould the stakes of the punters exceed the quantity in the meanwhile within the financial institution, the banker is not answerable for the quantity of such excess. In the occasion of their shedding, the croupier pays the punters so as of rotation, so far as the funds in the financial institution will extend; past this, they don't have any 1xbet korean claim. The banker might, nevertheless, in such a case, as an alternative of resting on his proper, declare the stakes accepted, putting up the needed funds to meet them. In such occasion the financial institution thenceforth turns into unlimited, and the banker should hold all stakes provided on any subsequent hand, or surrender the financial institution.
ReplyDeleteHi nice reading your bllog
ReplyDeleteThis was a llovely blog post
ReplyDelete