title: Mocking StoredProcedure with SimpleJDBCCall using DataSource
body: <p>I'm trying to create a unit test for a piece of code that was written by a team member no longer on the team. The class is using a SimpleJdbcCall with a DataSource that is autowired into the class.</p>
  <pre><code>@Component(&quot;DBHelper&quot;)
  public class DBHelper
  {
      private DataSource dataSource;
  
      public DBHelper()
      {
          // default constructor
      }
  
      @Autowired
      public DBHelper(@Qualifier(&quot;DBDatasource&quot;) final DataSource argDataSource)
      {
          this.dataSource = argDataSource;
      }
      
      @SuppressWarnings(&quot;unchecked&quot;)
      public List&lt;DataModel&gt; getData(final String argKey) throws Exception
      {
          List&lt;DataModel&gt; dataModel = null;
          
          try
          {
              SqlParameterSource request = new MapSqlParameterSource().addValue(&quot;key&quot;, &quot;;&quot;+argKey+&quot;;&quot;);
  
              Map&lt;String, Object&gt; response = new SimpleJdbcCall(dataSource).withProcedureName(&quot;stored_proc&quot;)
                      .returningResultSet(&quot;result&quot;, null).returningResultSet(&quot;result_2&quot;, new DBRowMapper())
                      .execute(request);
              dataModel = (List&lt;DataModel&gt;) response.get(&quot;result_2&quot;);
          }
           catch (final Exception e)
          {
              throw e;
          }
    
          return dataModel;
      }
  }
  </code></pre>
  <p>I have tried quite a few combinations of things but ultimately run into errors with:</p>
  <ol>
  <li>Failed to obtain JDBC Connection: DataSource returned null from getConnection(): mockDataSource - When I don't explicitly create a mock Connection</li>
  <li>An error with the DatabaseMetaData if I don't create a mock DatabaseMetaData</li>
  <li>java.lang.IllegalArgumentException: No Statement specified - With the code below</li>
  </ol>
  <p>I believed the issue was the process in which the SimpleJdbcCall and the SqlParameterSource were being created in the class, as new. So I implemented PowerMockito but still can't seem to get it working. I'm still new to Java and believe I have missing context as to what is going on behind the scenes but can't make out where I need to look.</p>
  <p>Here is the test class:</p>
  <pre><code>@ExtendWith(MockitoExtension.class)
  @PrepareForTest(DBHelperTest.class)
  class DBHelperTest {
  
      @Mock
      DataSource mockDataSource;
  
      @Mock
      Connection mockConnection;
  
      @Mock
      DatabaseMetaData mockMetaData;
  
      @Mock
      SimpleJdbcCall mockSimpleJdbcCall;
  
      @Mock
      MapSqlParamterSource mockMapSqlParameterSource;
  
      @Mock
      SqlParamterSource mockSqlParameterSource;
  
      private static Map&lt;String, Object&gt; mockJDBCResponse = getMockJDBCResponse();
  
      DBHelper subject;
  
      @BeforeEach
      void setUp() {
          subject = new DBHelper(mockDataSource);
      }
  
      @Test
      void getDBDataWithValidKey() throws Exception {
          // I tried using deep stub but couldn't get it to work
          doReturn(mockSimpleJdbcCall).when(mockSimpleJdbcCall).withProcedureName(anyString());
          doReturn(mockSimpleJdbcCall).when(mockSimpleJdbcCall).returningResultSet(anyString(), any(RowMapper.class));
          doReturn(mockSimpleJdbcCall).when(mockSimpleJdbcCall).returningResultSet(anyString(), any(RowMapper.class));
  
          PowerMockito.whenNew(SimpleJdbcCall.class).withArguments(mockDataSource).thenReturn(mockSimpleJdbcCall);
          
          // I tried to also mock the new creation of the MapSqlParameterSource but I cannot assign it to a mock type of SqlParameterSource, like what is done in the real class
          // PowerMockito.whenNew(MapSqlParameterSource.class).withNoArguments().thenReturn(mockMapSqlParameterSource);
          // doReturn(mockSqlParameterSource).when(mockMapSqlParameterSource).addValue(anyString(), anyString());
  
          doReturn(mockConnection).when(mockDataSource).getConnection();
          doReturn(mockMetaData).when(mockConnection).getMetaData();
  
          doReturn(mockJDBCResponse).when(mockSimpleJdbcCall).execute(any(SqlParameterSource.class));
  
          List&lt;DataModel&gt; actual = subject.getData(&quot;valid_key&quot;);
  
          assertThat(actual).isEqualTo(getTestDataModel());
      }
  
      private static Map&lt;String, Object&gt; getMockJDBCResponse() {
          Map&lt;String, Object&gt; mockMap = new HashMap&lt;&gt;();
  
          mockMap.put(&quot;rs1&quot;, getTestDataModel());
          mockMap.put(&quot;rs2&quot;, getTestDataModel());
  
          return mockMap;
      }
  }
  </code></pre>
  <p>Currently I am getting the &quot;java.lang.IllegalArgumentException: No Statement specified&quot; error but not sure what I am missing. The DBDataSource bean is:</p>
  <pre><code>@Configuration
  public class DBDataSourceConfiguration {
  
      @Bean(value = &quot;DBDatasource&quot;)
      @ConfigurationProperties(prefix = &quot;spring.datasource.db&quot;)
      public DataSource DBDatasource(){
          return DataSourceBuilder.create().build();
      }
  
      @Bean(&quot;DBTransactionManager&quot;)
      public DataSourceTransactionManager DBTransactionManager() {
          return new DataSourceTransactionManager(DBDatasource());
      }
  
  }
  </code></pre>