1

I'm trying to test my DAO class which has 2 dependancies, a dataSource and stringCrypto but the application keeps throwing

Failed to obtain JDBC Connection: DataSource returned null from getConnection(): dataSource

the datasource dependency that i'm trying to mock is a bean that uses JndiDataSourceLookUp which is

@Bean
public DataSource dataSource() {
    JndiDataSourceLookup dataSourceLookup = new JndiDataSourceLookup();

    dataSourceLookup.setResourceRef(true);

    DataSource dataSource = dataSourceLookup.getDataSource("castle/db");

    return dataSource;
}

This is the DAO Class

public class PersonDAOImpl implements PersonDAO {

@Autowired
private DataSource dataSource;

@Autowired
private Cryptography stringCrypto;

private NamedParameterJdbcTemplate namedParameterJdbcTemplate;

@Override
public List<Member> getAllMembers() {

    this.namedParameterJdbcTemplate = new NamedParameterJdbcTemplate(dataSource);

    try {
        List<Member> members = namedParameterJdbcTemplate.query(SqlStatement.GET_ALL_MEMBERS,
                new MemberExtractor());

        return members;
    } catch (Exception e) {
        e.printStackTrace();
        return null;

    }

}

as you can see in this class, it has 2 dependancies which i'm trying to mock in the test class below

@RunWith(SpringRunner.class)
public class MembersControllerTest {

@Mock
DataSource dataSource;

@Mock
Cryptography stringCrypto;

@InjectMocks
PersonDAOImpl personDAOImpl;

@BeforeEach
void setUp() {
    MockitoAnnotations.initMocks(this);
}

@Test
public void test() {

    assertTrue(personDAOImpl.getAllMembers().size() > 0);

}

}

i tried adding

@PostConstruct
private void initialization() {
    this.namedParameterJdbcTemplate = new NamedParameterJdbcTemplate(dataSource);
}

but it didn't work, and whenever i run my test it throws failed to obtain jdbc connection. the exception's that are getting thrown are not helpful at all, and all other similar questions are about configurating with xml and accepted answers are suggesting some xml configuration which i honestly don't really understand and i don't even want to use xml in my application. i really searched almost all the related questions and didn't find any of them helpful, so i decided to ask it.

thanks in advance

Amirreza Yegane
  • 185
  • 2
  • 10

1 Answers1

1

You are mocking only DataSource so still NamedParameterJdbcTemplate will call getConnection() to get connection and execute query. The recommended approach is declare NamedParameterJdbcTemplate as spring bean and then you need to mock it

Config class

@Bean
public DataSource dataSource() {
  JndiDataSourceLookup dataSourceLookup = new JndiDataSourceLookup();

  dataSourceLookup.setResourceRef(true);

  DataSource dataSource = dataSourceLookup.getDataSource("castle/db");

  return dataSource;
}

 @Bean
 public NamedParameterJdbcTemplate namedParameterJdbcTemplate(DataSource dataSource) {
   return new NamedParameterJdbcTemplate(dataSource);

}

Test class

 @RunWith(SpringRunner.class)
 public class MembersControllerTest {

     @Mock
     DataSource dataSource;

     @Mock
     Cryptography stringCrypto;

     @Mock
     NamedParameterJdbcTemplate namedParameterJdbcTemplate;

     @InjectMocks
     PersonDAOImpl personDAOImpl;

     @BeforeEach
     void setUp() {
         MockitoAnnotations.initMocks(this);
     }

  @Test
  public void test() {

    when(namedParameterJdbcTemplate.query(ArgumentMatchers.anyString(),
                                          ArgumentMatchers.any(MemberExtractor.class))
                                         .thenReturn(//List<Members>);
    assertTrue(personDAOImpl.getAllMembers().size() > 0);

     }

 }
Deadpool
  • 29,532
  • 9
  • 38
  • 73