Can anyone explain me the below scenario
Code to be tested
UserTransaction.java
@Override
public ServiceResponse<User> get(String name) {
ServiceResponse<User> response = new ServiceResponse<User>();
List<Map<String, Object>> exp = new ArrayList<Map<String, Object>>();
Map<String, Object> map = new HashMap<String, Object>();
map.put("expression", "eq");
map.put("property", "name");
map.put("value", name);
exp.add(map);
List<User> users = userDao.getByCriteria(exp);
if (!users.isEmpty()) {
response.setResponse(users.get(0));
} else {
response.setResponse(null);
}
return response;
}
UserDao.java
public List<User> getByCriteria(List<Map<String, Object>> exp) {
DetachedCriteria criteria = DetachedCriteria.forClass(User.class);
for (Integer i=0;i<exp.size();i++){
String expression = (String) exp.get(i).get("expression");
String property = (String) exp.get(i).get("property");
if(expression.equals("eq"){
criteria.add(Restrictions.eq(property,exp.get(i).get("value")));
}
}
return hibernateTemplate.findByCriteria(criteria);
}
UserTransactionTest.java
private UserTransaction userTransactions = new UserTransaction();
private UserDao userDao = mock(UserDao.class);
@Test
public void testGet() {
User user = new User();
user.setName("Raman");
try {
when(userDao.getByCriteria(anyList())).thenReturn(user);
} catch (Exception e) {
e.printStackTrace();
}
ServiceResponse<User> response = userTransactions.get("raman");
User result = response.getResponse();
assertEquals("Raman", result.getName());
assertEquals(0, response.getErrors().size());
}
works fine.
But instead of "anyList()" I passed a user-defined list "myList"
List<Map<String,Object>> myList = new ArrayList<Map<String,Object>>();
Map<String,Object> map = new HashMap<String,Object>();
map.put("expression","eq");
map.put("property","name");
map.put("value","raman");
myList.add(map);
when(userTransactions.getByCriteria(myList)).thenReturn(user);
Throws NullPointerException
at the line assertEquals()
. Why? What actually happens if anyList()
is given?
NullPointerException is thrown when a reference variable is accessed (or de-referenced) and is not pointing to any object. This error can be resolved by using a try-catch block or an if-else condition to check if a reference variable is null before dereferencing it.
thenReturn or doReturn() are used to specify a value to be returned upon method invocation. //”do something when this mock's method is called with the following arguments” doReturn("a").
How to avoid the NullPointerException? To avoid the NullPointerException, we must ensure that all the objects are initialized properly, before you use them. When we declare a reference variable, we must verify that object is not null, before we request a method or a field from the objects.
NullPointerException is thrown when an application attempts to use an object reference that has the null value. These include: Calling an instance method on the object referred by a null reference. Accessing or modifying an instance field of the object referred by a null reference.
I'm sure you've already solved your problem by now, but in case anyone stumbles upon the same issue, here's the answer:
In the code you've provided, you are not using the mocked myList
you've created. The get()
method always calls userDao.getByCriteria(exp)
, a local variable.
This is why anyList()
works, while myList
doesn't.
If you do want to test the expression, List<Map<String,Object>> exp
should be a member of your class, not a local variable:
public class UserTransaction {
private List<Map<String,Object>> exp;
public UserTransaction() {
// creating a default exp value
Map<String, Object> map = new HashMap<String, Object>();
map.put("expression", "eq");
map.put("property", "name");
map.put("value", name);
exp.add(map);
}
// getters and setters for exp
public ServiceResponse<User> get(String name) {
ServiceResponse<User> response = new ServiceResponse<User>();
List<User> users = userDao.getByCriteria(exp);
if (!users.isEmpty()) {
response.setResponse(users.get(0));
} else {
response.setResponse(null);
}
return response;
}
}
And in your Test:
private UserTransaction userTransactions = new UserTransaction();
private UserDao userDao = mock(UserDao.class);
@Test
public void testGet() {
User user = new User();
user.setName("Raman");
// creating a custom expression
List<Map<String,Object>> myList = new ArrayList<Map<String,Object>>();
Map<String,Object> map = new HashMap<String,Object>();
map.put("expression","eq");
map.put("property","name");
map.put("value","raman");
myList.add(map);
// replacing exp with the list created
userTransactions.setExp(myList);
// return user when calling getByCriteria(myList)
when(userDao.getByCriteria(myList)).thenReturn(user);
ServiceResponse<User> response = userTransactions.get("raman");
User result = response.getResponse();
assertEquals("Raman", result.getName());
assertEquals(0, response.getErrors().size());
}
If your code is complete (I suspect it may not be) then you haven't specified the mock object that contains the get()
method. This should be present in the call to when(...)
I am expecting code like this...
UserDao mockDao = mock(UserDao.class);
when(mockDao.get(list)).thenReturn(users);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With