4

I am trying to unit test this method:

/**
     * finds all widget descriptions containing specified text
     * @param searchText
     * @return
     */
    @Transactional
    public List<Integer> returnWidgetIdsFromSearchWord(String searchText){
        List<Integer> widgetIds = new ArrayList<Integer>();
        MapSqlParameterSource args = new MapSqlParameterSource();

        try{
            widgetIds = (List<Integer>) jdbt.queryForList("SELECT idwidgets FROM descriptions "
                    + "WHERE descriptiontext LIKE '%"+ searchText + "%'", args, Integer.class);
        }catch(Exception e){

        }

        return widgetIds;
    }

with this JUnit test:

@Test
    public void testReturnWidgetIdsFromSearchWord(){
        List<Integer> widgetIds = null;

        when(jdbt.queryForList(Matchers.anyString(), 
                Matchers.any(MapSqlParameterSource.class),
                 Matchers.any(Integer.class))).thenReturn(idList);

        widgetIds = (List<Integer>) dDao.returnWidgetIdsFromSearchWord("someText");

        assertEquals(widgetIds, idList);
    }

I have tried just use Integer.class without the Matcher - no luck because then it complains about needing 3 matchers. Any suggestions? And thanks

eggshell
  • 113
  • 1
  • 2
  • 8
  • 1
    You might need to check this out http://stackoverflow.com/questions/2631596/how-to-properly-match-varargs-in-mockito because googling about queryForList it taskes a String and an Object... varargs http://docs.spring.io/spring/docs/2.5.6/api/org/springframework/jdbc/core/JdbcTemplate.html But I don't know what version of the interface you are using. – Eric Woodruff Jan 29 '14 at 20:15
  • 1
    Is `jdbt` meant to be a `JdbcTemplate`? If so, your code doesn't seem to compile. – Sotirios Delimanolis Jan 29 '14 at 20:16
  • yes, jdbt is NamedParameterJdbcTemplate and it is mocked in setup. The original method compiles and returns the expected List – eggshell Jan 29 '14 at 20:27

3 Answers3

10

Do not cast Matchers.anyVararg(), there is better solution.

Method queryForList has signature

queryForList(String sql, SqlParameterSource paramSource, Class<T> elementType)

so instead of

when(jdbt.queryForList(Matchers.anyString(), 
                       Matchers.any(MapSqlParameterSource.class),
                       Matchers.any(Integer.class))).thenReturn(idList); 

use

when(jdbt.queryForList(Matchers.anyString(), 
                       Matchers.any(MapSqlParameterSource.class), 
                       Matchers.<Class<Integer>>any())).thenReturn(idList);

as described in Mockito: Verifying with generic parameters


Do not use code with anyVararg() and casting

when(jdbt.queryForList(Matchers.anyString(), 
                       Matchers.any(MapSqlParameterSource.class), 
                       (Class<Object>) Matchers.anyVararg()).thenReturn(idList);

because this generate warning

Unchecked cast: `java.lang.Object` to `java.lang.Class<java.lang.Object>`
Community
  • 1
  • 1
MariuszS
  • 30,646
  • 12
  • 114
  • 155
  • 1
    I tried this one as well, it does not pass either. Also, I never got an "Unchecked cast" warning. Thanks though – eggshell Jan 29 '14 at 22:14
1

If you need to mock NamedParameterJdbcTemplate#queryForList(String, SqlParameterSource, Class) then just use

when(jdbt.queryForList(Matchers.anyString(), Matchers.any(SqlParameterSource.class), Matchers.any(Class.class))).thenReturn(idList);

Is it possible that you didn't pass your template object to the DAO instance? Find my full test class below. It passes the test successfully:

import static org.junit.Assert.*;
import static org.mockito.Matchers.*;
import static org.mockito.Mockito.*;

import java.util.ArrayList;
import java.util.List;

import org.junit.Test;
import org.mockito.Mockito;

public class DebugTest {

    private MyDao dDao;

    private final NamedParameterJdbcTemplate jdbt = mock(NamedParameterJdbcTemplate.class);

    @SuppressWarnings("unchecked")
    @Test
    public void testReturnWidgetIdsFromSearchWord() {
        final List<Integer> idList = new ArrayList<Integer>();

        this.dDao = new MyDao(this.jdbt);

        when(this.jdbt.queryForList(anyString(), any(SqlParameterSource.class), any(Class.class)))
            .thenReturn(idList);

        final List<Integer> widgetIds = this.dDao.returnWidgetIdsFromSearchWord("Hallo");

        assertEquals(widgetIds, idList);

    }

    private static class MyDao {
        private final NamedParameterJdbcTemplate jdbt;

        public MyDao(final NamedParameterJdbcTemplate jdbt) {
            this.jdbt = jdbt;
        }

        public List<Integer> returnWidgetIdsFromSearchWord(final String searchText) {
            List<Integer> widgetIds = new ArrayList<Integer>();
            SqlParameterSource args = new MapSqlParameterSource();

            try {
                widgetIds = (List<Integer>) jdbt.queryForList("SELECT idwidgets FROM descriptions "
                    + "WHERE descriptiontext LIKE '%"+ searchText + "%'", args, Integer.class);
            } catch(Exception e) {

            }

            return widgetIds;
        }
    }
}
Peter Keller
  • 7,526
  • 2
  • 26
  • 29
-1

I changed my test to this and it worked:

@Test
    public void testReturnWidgetIdsFromSearchWord(){
        List<Integer> widgetIds = null;
        String searchText = "someText";

        /*when(jdbt.queryForList("SELECT idwidgets FROM descriptions "
                + "WHERE descriptiontext LIKE '%"+ searchText + "%'", 
                args, Integer.class)).thenReturn(idList);*/

        when(jdbt.queryForList(Matchers.anyString(), Matchers.any(MapSqlParameterSource.class), 
                (Class<Integer>) Matchers.anyVararg())).thenReturn(idList);

        widgetIds = (List<Integer>) dDao.returnWidgetIdsFromSearchWord(searchText);

        System.out.println(widgetIds.size());

        assertEquals(widgetIds, idList);
    }

Thanks for the help

eggshell
  • 113
  • 1
  • 2
  • 8
  • 2
    please, please, please in real life, use the static imports for the Mockito static methods, or else it becomes really a lot harder to take in the simplicity of your `when` clauses with the static matcher method calls – Kevin Welker Jan 30 '14 at 00:05