2016-05-20 7 views
0

Ich versuche, ein Verfahren zur Herstellung EntityPersistorMockito Mock Methode mit Parametern vergleichen - Misplaced Argument Matcher hier erkannt

T getSingleResultFromTypedQuery(String queryString, Map<String, Object> params); 

ich überprüfen möchten zu verspotten, wenn querystring eine bestimmte querystring übereinstimmt und wenn params einen bestimmten Wert enthält. Wenn diese beiden Bedingungen zutreffen, möchte ich ein spezifisches Objekt xy zurückgeben.

Ich bin neu zu Spott und Mockito, aber ich habe versucht, dies mit zwei ArgumentMatcher innerhalb der When() -Aufruf zu erreichen.

EntityPersistor<UserEntity> entityPersistorMocked = mock(EntityPersistorStub.class); 

when(entityPersistorMocked.getSingleResultFromTypedQuery(argThat(new ArgumentMatcher<String>() { 
     @Override 
     public boolean matches(Object o) { 
      return "SELECT u FROM UserEntity u where u.username = :u".equals(o.toString()); 
     } 
    }), argThat(new ArgumentMatcher<Map<String, Object>>() { 
     @Override 
     public boolean matches(Object o) { 
      HashMap<String, Object> params = (HashMap<String, Object>) o; 
      if (params.containsKey('u') && params.get('u').toString().equals("hans")) { 
       return true; 
      } else { 
       return false; 
      } 
     } 
    }))) 
      .thenAnswer(new Answer<UserEntity>() { 
       @Override 
       public UserEntity answer(InvocationOnMock invocation) throws Throwable { 
        UserEntity user = new UserEntity(); 
        user.setUserId(1); 
        user.setDisplayName("Dummy User"); 
        user.setUsername("hans"); 
        user.setPassword("pass"); 
        return user; 
       } 
      }); 

kompiliert erfolgreich, aber nicht ausgeführt werden:

org.mockito.exceptions.misusing.InvalidUseOfMatchersException: 

Misplaced Argument Matcher hier entdeckt:

wie kann ich das Problem lösen? Oder gibt es einen besseren Weg, eine Methode zu verspotten und einen spezifischen Return-Case zu definieren (wenn param 1 eq x und param 2 eq y)?

Antwort

1

ich gerade tun:

Answer<UserEntity> answer = new Answer<UserEntity>() { 
    public UserEntity answer(InvocationOnMock invocation) throws Throwable { 
     String queryString = (String) invocation.getArgument(0); 
     Map params = (Map) invocation.getArgument(1); 
     if ("foo".equals(queryString) && params.containsKey("bar")) { 
      return x; 
     } else { 
      return y; 
     } 
    } 
}; 
when(mock.getSingleResultFromTypedQuery(anyString(), any(Map.class)).thenAnswer(answer); 
0

sollten Sie in der Lage sein, Ihren Code ein bisschen einfach, indem Sie zu vereinfachen:

EntityPersistor<UserEntity> entityPersistorMocked = mock(EntityPersistorStub.class); 

HashMap<String, Object> expectedParams = (HashMap<String, Object>) o; 
expectedParams.put("u", "hans"); 


UserEntity user = new UserEntity(); 
user.setUserId(1); 
user.setDisplayName("Dummy User"); 
user.setUsername("hans"); 
user.setPassword("pass"); 
return user; 

when(entityPersistorMocked.getSingleResultFromTypedQuery("SELECT u FROM UserEntity u where u.username = :u", expectedParams)).thenReturn(user); 

nur sicherstellen, dass die Werte in der Karte gleich sein können (in Ihrem Fall mit Strings sollte es funktionieren, aber für ein beliebiges Objekt, das keine gleichwertige Methode hat, wird Mockito nicht herausfinden, dass das Objekt, das Sie übergeben, das gleiche (Wert) wie das erwartete ist.