Spring JdbcNamedParameterTemplate Junit Mockito

Introduction

In the tutorial, Spring NamedParameterJdbcTemplate and MapSqlParameterSource Example, I had shown how to save new record in the database and how to fetch record from database. Here I am going to show you how to mock Spring JdbcNamedParameterTemplate SqlParameterSource with Junit Mockito.

I am going to use Junit 5 framework for this example. I am also using Mockito framework to mock objects. For testing void method I will use Mockito.verify() to check how many times a void method gets executed. There is no other way to verify the void method because void method does not return anything.

I am going to test the query method from NamedParameterJdbcTemplate when the DAO class has the void method.

NamedParameterJdbcTemplate junit

Prerequisites

Java 1.8+, Maven 3.6.3 – 3.8.2, Spring Boot 2.3.2 – 2.5.5, Junit 5

Make sure you are reading the tutorial Spring NamedParameterJdbcTemplate and MapSqlParameterSource Example though I have provided the whole source code for this example later in the Source Code section.

Mock DAO, NamedParameterJdbcTemplate – update() and queryForObject()

Here I am not going to explain NamedParameterJdbcTemplate and its method but you can check my previous tutorial on Spring NamedParameterJdbcTemplate and MapSqlParameterSource Example.

Let’s look at the code snippets:

@ExtendWith(MockitoExtension.class)
public class NamedParameterJdbcTemplateTest {

	@Mock
	private UserDao dao;

	@InjectMocks
	private UserDao userDao;

	@Mock
	private NamedParameterJdbcTemplate namedParameterJdbcTemplate;

      …
}

In Junit 5, when you are using Mockito framework, you need to annotate the class with @ExtendWith(MockitoExtension.class), unlike Junit 4, where you need to either annotate the class with @RunWith(JunitMockitoRunner.class) or you need to use the following to initialize your mock objects:

@Before
Public void setup() {
   MockitoAnnotations.initMocks(this);
}

Now let’s come back to the example code snippets. In the above class NamedParameterJdbcTemplateTest, notice I have used UserDao twice. So dao instance is a Mock instance whereas userDao instance is a Mock instance as well as other Mock instance will be injected into this instance. For example, namedParameterJdbcTemplate will be injected into userDao instance.

Let’s look at the test method below:

@Test
public void testAddUser() {
	User user = new User(1, "Soumitra", "soumitra@roytuts.com", "1234567890", "Earth");

	dao.addUser(user);

	Mockito.verify(dao, Mockito.times(1)).addUser(user);
}

In the above test method I am just calling the addUser() method of DAO class and verifying whether the addUser() method was called only once or not. So in this test method I am not actually testing any method of NamedParameterJdbcTemplate class.

Let’s look at the following test method:

@Test
public void testAddUserJdbcNamedParameter() {
	final String sql = "insert into user(id, name, email, phone, address) values(:id, :name, :email, :phone, :address)";

	User user = new User(1, "Soumitra", "soumitra@roytuts.com", "1234567890", "Earth");

	MapSqlParameterSource mapParameters = new MapSqlParameterSource();
	mapParameters.addValue("id", user.getId());
	mapParameters.addValue("name", user.getName());
	mapParameters.addValue("email", user.getEmail());
	mapParameters.addValue("phone", user.getPhone());
	mapParameters.addValue("address", user.getAddress());

	Mockito.when(namedParameterJdbcTemplate.update(Mockito.anyString(), Mockito.any(MapSqlParameterSource.class)))
			.thenReturn(1);

	userDao.addUser(user);

	Assertions.assertEquals(1, namedParameterJdbcTemplate.update(sql, mapParameters));
}

In the above test method, see that I am actually testing the NamedParameterJdbcTemplate’s method update() which is used to insert a new record in the database table.

I am using Mockito framework to mock the update method that will return 1 and calling the actual DAO class’s method addUser() using the Mock instance of userDao.

Now let’s look at the test method below:

@Test
public void testCountByName() {
	User user = new User(1, "Soumitra", "soumitra@roytuts.com", "1234567890", "Earth");

	Integer integer = new Integer(1);

	Mockito.when(namedParameterJdbcTemplate.queryForObject(Mockito.anyString(),
			Mockito.any(SqlParameterSource.class), Mockito.<Class> any())).thenAnswer(x -> integer);

	int i = userDao.countByName(user);

	Assertions.assertEquals(1, i);
}

The above test method actually test the count of records from the database table.
I have used Mockito framework to mock the queryForObject() method of NamedParameterJdbcTemplate class.

Notice the last parameter is Mockito. any() of queryForObject() method instead of simply putting Mockito.any(Integer.class). If you put simply Mockito.any(Integer.class), then it will throw compilation error because it will try to match with RowMapper as a last parameter instead of Class<T> requiredType.

Also notice I have used thenAnswer(x -> integer) instead of thenReturn() because of the last parameter Mockito. any() in the method queryForObject() method. You cannot simply return thenReturn(1) or thenReturn(Integer.valueOf(1)) or thenReturn(new Integer(1)) or thenAnswer(1) or thenAnswer(Integer.valueOf(1)) or thenAnswer(new Integer(1)), you will get compilation error.

Finally verifying the result with assertion.

Testing NamedParameterJdbcTemplate Junit Tests

Executing the test class NamedParameterJdbcTemplateTest will pass your tests.
Hope you got an idea how to mock NamedParameterJdbcTemplate – update() and queryForObject() in Junit 5.

Source Code

Download

Leave a Reply

Your email address will not be published. Required fields are marked *