JdbcTemplate Mockito ClassCastException

1.7k views Asked by At

I am trying to mock a method of the Spring framework's JdbcTemplate class. The method has the following signature:

public <T> T queryForObject(String sql, Class<T> requiredType) throws DataAccessException {...}

The mocking is being done as mentioned below:

when(jdbcTemplate.queryForObject(anyString(), eq(String.class))).thenReturn("data");

However, this call throws the following exception

java.lang.ClassCastException: org.mockito.internal.creation.jmock.ClassImposterizer$ClassWithSuperclassToWorkAroundCglibBug$$EnhancerByMockitoWithCGLIB$$ce187d66 cannot be cast to java.lang.String
at test.DaoJdbcTest.setUp(DaoJdbcTest.java:81)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
...

Any idea as to what I am doing wrong?

Thanks in advance~

EDIT:

Here's the full code:

public class DaoJdbc extends NamedParameterJdbcSupport {
    public String query(String sql) {
        return getJdbcTemplate().queryForObject(sql, String.class);
    }
}

public class DaoJdbcTest {
    @Mock(answer = Answers.RETURNS_SMART_NULLS)
    private JdbcTemplate jdbcTemplate;

    private DaoJdbc dao;

    @Before
    public void setUp() throws Exception {
        MockitoAnnotations.initMocks(this);

        dao = new DaoJdbc();
        dao.setJdbcTemplate(jdbcTemplate);

        Mockito.when(jdbcTemplate.queryForObject(anyString(), Matchers.eq(String.class))).thenReturn("data");
    }

    @Test
    public void testQuery() {
        String ret = dao.query("select 'test' from dual");

        assertEquals("data", ret);

        verify(jdbcTemplate).queryForObject(anyString(), eq(String.class));
    }
}
1

There are 1 answers

1
hyness On BEST ANSWER

Remove the answer = Answers.RETURNS_SMART_NULLS. Test passes when I remove that. What does that feature do? The default null behavior works fine for me.

As a bonus, you can also use the MockitoJunitRunner to clean up the code a bit...

@RunWith(MockitoJUnitRunner.class)
public class DaoJdbcTest {
    @Mock
    private JdbcTemplate jdbcTemplate;

    @InjectMocks
    private DaoJdbc dao;

    @Before
    public void setUp() throws Exception {
        Mockito.when(jdbcTemplate.queryForObject(anyString(), Matchers.eq(String.class))).thenReturn("data");
    }

    @Test
    public void testQuery() {
        String ret = dao.query("select 'test' from dual");

        assertEquals("data", ret);

        verify(jdbcTemplate).queryForObject(anyString(), eq(String.class));
    }
}