Mockito模拟方法与比较参数 - 错误的参数匹配器在这里检测到

时间:2016-05-20 13:49:01

标签: java unit-testing testing mocking mockito

我试图模仿EntityPersistor的方法

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

我想检查queryString是否与特定的queryString匹配,以及params是否包含特定值。如果这两个条件成立,我想返回一个特定的对象xy。

我是嘲笑和模拟的新手,但我试图在when()调用中使用两个ArgumentMatcher实现此目的。

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

编译成功,但不会运行:

org.mockito.exceptions.misusing.InvalidUseOfMatchersException: 
     

此处检测到错位的参数匹配器:

我该如何解决?或者有更好的方法来模拟方法并定义一个特定的返回案例(如果param 1 eq x和param 2 eq y)?

2 个答案:

答案 0 :(得分:1)

我只是这样做:

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

答案 1 :(得分:0)

您应该能够简单地简化代码:

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

只需确保地图中的值可以相等检查(在你的情况下使用字符串它应该可以工作但是对于某些任意对象没有相同的方法mockito将无法找到你传递的对象in与预期值相同(值)..