2012-08-15 14 views
6

Czy ktoś może wyjaśnić mi Poniższy scenariusz
kod do testowania
UserTransaction.java
Junit Mockito kiedy (..). ThenReturn() rzuca NullPointerException

@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()); 
} 

działa dobrze.

Ale zamiast "anyList()" minąłem listy zdefiniowane przez użytkownika "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); 

rzuca NullPointerException na linii assertEquals(). Czemu? Co się dzieje, jeśli podano anyList()?

+0

Jesteś nie publikujemy wystarczającej ilości kodu, co utrudnia innym zorientowanie się, co dzieje się źle. Czy 'when (userTransactions' jest błędem ortograficznym? Jak powstaje' myList', jaka jest sygnatura metody 'getByCriteria()'? – Brad

+2

Czy tu czegoś brakuje? Nadal publikujesz 'kiedy (userTransactions ...' i ten obiekt nie został utworzony.} Utworzono 'userTransaction' w powyższym kodzie, ale nie" userTransactions "(uwaga na" s "na końcu) .Jeśli debugujesz swój kod czy istnieje obiekt o nazwie 'userTransactions' i czy jest to wyśmiewany obiekt? – Brad

+0

Czy możesz wyjaśnić, czy to rzuca wyjątek na linii z' when', czy na linii w teście, gdzie 'getByCriteria' jest rzeczywiście wywoływana? więcej twojego kodu - jak powiedzieli inni, tak naprawdę nie dostarczyłeś wystarczającej ilości informacji, abyśmy mogli zdiagnozować, co jest nie tak, –

Odpowiedz

0

myślę anyList() jest metodą, która jesteś szyderczy i lista nie jest metoda, można proszę umieszczać kod źródłowy, co piszesz to przypadek testowy

+2

anyList() to metoda matchera w Mockito –

4

Jeśli kod jest kompletny (podejrzewam może nie być), a następnie nie określono obiektu próbnego, który zawiera metodę get(). To powinno być obecne w zaproszeniu do when(...)

mam kod jak to spodziewa ...

UserDao mockDao = mock(UserDao.class); 

when(mockDao.get(list)).thenReturn(users); 
+0

Zrobiłem jak wyżej. jest, gdy przekazuję anyList() jako parametr, który test przeszedł, ale kiedy przekażę zdefiniowaną przez użytkownika "listę", generuje wyjątek. – user1600577

0

Przede wszystkim nie testują UserDao.

Następnie anyList() produkuje mockito matcher i powinieneś przekazać matcher do userDao.getByCriteria, aby coś zrobić, więc powinieneś użyć Matchers.same (twoja lista) lub Matchers.eq (twoja lista).

Pojawia się wyjątek, ponieważ domyślnie Mockito tworzy ładne makiety i domyślnie zwraca wartość NULL w przypadku nieoczekiwanego wywołania metody.

4

Jestem pewien, że już rozwiązany problem teraz, ale w przypadku gdy ktoś potknie się na tym samym numerze, oto odpowiedź:

W kodzie już dostarczonych, nie są przy użyciu szydzili myList został utworzony. Metoda get() zawsze wywołuje userDao.getByCriteria(exp), zmienną lokalną.

To dlatego anyList() działa, a myList nie.

Jeśli zrobić chcą przetestować wyrażenie, List<Map<String,Object>> exp powinien być członkiem swojej klasie, a nie zmienna lokalna:

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; 
    } 
} 

A w teście:

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()); 
} 
Powiązane problemy