Spring JUnit and Mockito - SimpleJdbcTemplate

10,406

Instead of mocking the concrete class, you ought to be mocking an interface (which has the methods you need).

e.g.:

public class SimpleJdbcDaoSupportExtension extends SimpleJdbcDaoSupport implements MyDomainDao{  
     public SimpleJdbcDaoSupportExtension (JdbcTemplate jdbcTemplate){  
             super.setJdbcTemplate(jdbcTemplate);  
     }

     public MyDomainObj getResult(){
         SimpleJdbcTemplate sjdbc = getSimpleJdbcTemplate();  
         MyDomainObj result = sjdbc.query(*whatever necessary args*.);
         return result;
     }
}

public class Test {  
    @Mock private MyDomainDao myDomainDao ;
    private YourController yourController;  

    @Before
    public void doBeforeEachTestCase() {
        MockitoAnnotations.initMocks(this);
        yourController = new YourController(myDomainDao);
    }  
    @Test
    public final void testSomething(){           
        when(myDomainDao.getResult().thenReturn(new MyDomainObj());
        //on to testing the usages of myDomainDao
        yourController.doSomething();
        //verify
        verify(myDomainDao, times(2)).getResult();
    }
}
Share:
10,406
Admin
Author by

Admin

Updated on June 14, 2022

Comments

  • Admin
    Admin almost 2 years

    Given a class that extends SimpleJdbcDaoSupport, how can you mock SimpleJdbcTemplate?

    public class SimpleJdbcDaoSupportExtension extends SimpleJdbcDaoSupport {  
         public SimpleJdbcDaoSupportExtension (JdbcTemplate jdbcTemplate){  
                 super.setJdbcTemplate(jdbcTemplate);  
         }
    
         public MyDomainObj getResult(){
             SimpleJdbcTemplate sjdbc = getSimpleJdbcTemplate();  
             MyDomainObj result = sjdbc.query(*whatever necessary args*.);
             return result;
         }
    }
    

    Then, using Mockito:

    public class Test {  
        @Mock private JdbcTemplate mockedJdbcTemplateDedendency;  
        private SimpleJdbcDaoSupportExtension testObj;  
    
        @Before
        public void doBeforeEachTestCase() {
            MockitoAnnotations.initMocks(this);
            SimpleJdbcDaoSupportExtension sje = new SimpleJdbcDaoSupportExtension (mockedJdbcTemplateDedendency);
        }  
        @Test
        public final void test(){           
            when(mockedJdbcTemplateDedendency.query("what to query").thenReturn(new MyDomainObj());
        }
    }
    

    The mocked JdbcTemplate is injected, but since the dao class relies on SimpleJdbcTemplate to make queries (for mapping to objects), and it's constructed internally by SimpleJdbcDaoSupport - mocking JdcbTemplate has no effect on the SimpleJdbcTemplate. So how to do this, when there are no public setters for it, and the only way to construst SimpleJdbcTemplate is to rely on that method, getSimpleJdbcObject()?

  • Juan Antonio Gomez Moriano
    Juan Antonio Gomez Moriano about 11 years
    I have always wondered, if you use HSQL instead of mocking you would be somehow doing not really a unit test by some kind of integration test, am i right?
  • Sean Patrick Floyd
    Sean Patrick Floyd about 11 years
    @JuanAntonioGomezMoriano from a purists's point of view, yes. I find that the borders between unit and integration tests are not clearly defined. The definition I find most useful (although not semantically correct) is: A Unit Test is anything that doesn't require external services, and integration test is everything else. From that point of view, in memory DBs are ok for unit tests.
  • Juan Antonio Gomez Moriano
    Juan Antonio Gomez Moriano about 11 years
    Thanks for the explanation :)
  • Rogério
    Rogério over 9 years
    An accurate answer to your question is that you would need to use a mocking library which supports the mocking of unspecified implementation classes from a given base type. JMockit (a mocking tool I develop) provides said support through the @Capturing annotation, used to declare a mock field/parameter.
  • Stunner
    Stunner about 3 years
    @SeanPatrickFloyd what about if my code used 50+ tables with 200+ columns in each table. You create whole db schema in unit tests?? I don't get the point..