0

I have followign piece of code

@Repository
public class ServiceImpl implements MyService {
  @Autowired
  private ConnectionFactory factory;

  private List<Map<String, Object>> execute(String source, String schemaName, String query) {
    return getJdbcTemplate(source, schemaName).queryForList(query);
  }

  private JdbcTemplate getJdbcTemplate(String source, String schemaName) {
    return new JdbcTemplate(factory.getDataSource(source, schemaName));
  }
  @Override
  public List<Map<String, Object>> findAll(String source, String schemaName) {
    String query = "query";
    return execute(source, schemaName, query);
  }
}

My testing code

@RunWith(SpringJUnit4ClassRunner.class)
public class ServiceImplTest {

  @Mock
  private ConnectionFactory connectionFactory;

  @Mock
  private DataSource dataSource;

  @Mock
  private JdbcTemplate template;

  @InjectMocks
  private final ServiceImpl serviceImpl = new ServiceImpl();

  @Before
  public void setUp() throws Exception {
  }

  @Test
  public final void testFindAll() {
    Map<String, Object> map = new HashMap<>();
    map.put("k1", "v1");
    List<Map<String, Object>> l = new ArrayList<>();
    l.add(map);
    when(connectionFactory.getDataSource(any(), any())).thenReturn(dataSource);
    when(template.queryForList(any())).thenReturn(l);
    List<Map<String, Object>> findAllCustomFieldDefs = serviceImpl.findAll(any(), any());
    assertNotNull(findAllCustomFieldDefs);

  }

When I run this then

return getJdbcTemplate(source, schemaName).queryForList(query); is throwing

org.springframework.jdbc.CannotGetJdbcConnectionException: Failed to obtain JDBC Connection: DataSource returned null from getConnection(): dataSource
    at org.springframework.jdbc.datasource.DataSourceUtils.getConnection(DataSourceUtils.java:84)
    at org.springframework.jdbc.core.JdbcTemplate.execute(JdbcTemplate.java:371)
    at org.springframework.jdbc.core.JdbcTemplate.query(JdbcTemplate.java:452)
    at org.springframework.jdbc.core.JdbcTemplate.query(JdbcTemplate.java:462)
    at org.springframework.jdbc.core.JdbcTemplate.queryForList(JdbcTemplate.java:490)
Manish Kumar
  • 10,214
  • 25
  • 77
  • 147

1 Answers1

1

You are mocking JdbcTemplate and setting expectations on a mocked instance, while your service is not using this mock at all and creates a new instance.

private JdbcTemplate getJdbcTemplate(String source, String schemaName) {
    return new JdbcTemplate(factory.getDataSource(source, schemaName));
}

Don't create a new JdbcTemplate in your service. It is perfectly legal to inject a JdbcTemplate bean: using Spring JdbcTemplate - injecting datasource vs jdbcTemplate

Lesiak
  • 22,088
  • 2
  • 41
  • 65