Reputation: 355
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
Upvotes: 1
Views: 4724
Reputation: 40048
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);
}
}
Upvotes: 1