java 如何在JUnit测试中模拟对JdbcTemplate.query(String,Object[],int[] RowMapper)的调用< T>?(特别是数组)

piah890a  于 2023-05-12  发布在  Java
关注(0)|答案(2)|浏览(267)

我想在JdbcTemplate中模拟这个方法:

public <T> List<T> query(String sql, Object[] args, int[] argTypes, RowMapper<T> rowMapper) throws DataAccessException {
        return result(query(sql, args, argTypes, new RowMapperResultSetExtractor<>(rowMapper)));
    }

我使用JUnit 5和Hamcrest。
我试过很多方法,我觉得最有效的方法是:

when(db.query(anyString(), any(Object[].class), any(int[].class), new IdRowMapperImpl())).thenReturn(profileIds);

但事实并非如此我做错了什么?我如何模拟数组?

nkoocmlb

nkoocmlb1#

如果使用参数匹配,则所有参数都应该是相同的类型。在您的情况下,例如:

when(jdbcTemplate.query(
                anyString(),
                any(Object[].class),
                any(int[].class),
                any(RowMapper.class)
        )).thenReturn(profileIds);
e5njpo68

e5njpo682#

您认为应该工作的mock不会工作,因为您同时使用了参数匹配器和显式值。如果你想在匹配器中使用一个显式的值,你需要让mockito知道eq匹配器。

when(db.query(anyString(), any(Object[].class), any(int[].class), eq(new IdRowMapperImpl()))).thenReturn(profileIds);

但是,这也不会起作用,因为new IdRowMapperImpl()将是一个与实际查询中传递的对象不同的对象。
最后,在when模拟过程中声明特定类型通常会适得其反。除非您希望根据传递的值专门返回不同的对象,否则when(db.query(any(), any(), any(), any())).thenReturn(profileIds);也同样有用。然后,您可以使用verify来Assert预期的方法已被调用,并且预期的值实际上已传递给它。
也许是这样的:

@Test
public void testRetrieveData()
{
  String expectedQuery = "THIS IS MY QUERY";
  ArgumentCaptor<Object> objectCaptor = ArgumentCaptor.forClass(Object.class);
  ArgumentCaptor<RowMapper> mapperCaptor = ArgumentCaptor.forClass(RowMapper.class);
  when(db.query(any(), any(), any(), any())).thenReturn(profileIds);
 
  MyDao.getMyData();

  verify(db, times(1)).query(eq(expectedQuery), (Object[]) objectCaptor .capture(), any(int[].class), mapperCaptor.capture());
  assertEquals(expectedObjectArray, objectCaptor.getValue());
  assertTrue(mapperCaptor.getValue() instanceof IdRowMapperImpl);
}

相关问题