Replacing DataSource in Mockito
Solution 1
Since you're using @Mock
, there is no need to actually instantiate those objects by calling their constructors.
Instead of:
@Mock
BasicDataSource dataSource = new BasicDataSource();
@Mock
JNDIBasedDao dao = new JNDIBasedDao();
try:
@Mock
BasicDataSource dataSource;
@Mock
JNDIBasedDao dao;
and let Mockito handle creating mock versions of those classes.
Of course, when you do this you get Mock versions of these classes, so calling all those methods on your dataSource would result in calls to default Mockito stubbings...which do nothing.
Not sure why you've combined @Mock
with method calls on the same object which it looks like you expect to have a result...
Maybe step through the debugger and check the runtime class of the objects youre using at the point the exception is thrown. They might not be what you expect them to be.
Solution 2
@InjectMocks will do only setter injection.
Change the following in Manager class
private JNDIBasedDao dao = new JNDIBasedDao();
to
private JNDIBasedDao dao;
and add
void setDao(JNDOBasedDao dao)
{
this.dao = dao;
}
Solution 3
You could create a second constructor and inject the InitialContext.
public class JNDIBasedDao {
DataSource dataSource;
public JNDIBasedDao() {
this(new InitialContext());
}
public JNDIBasedDao(InitialContext ic) {
try {
dataSource = (DataSource) ic.lookup("java://bla-bla-bla");
} catch (NamingException e) {
e.printStackTrace();
}
}
....
}
Now you're able to provide a mocked InitialContext, which provides your DataSource.
danny.lesnik
Java Expert at Tikal Knowledge. Interesting in Spring/Hibernate/NoSQL/Spring MVC and other Java top edge technology. Twitter LinkedIn Facebook
Updated on June 04, 2022Comments
-
danny.lesnik almost 2 years
I have code which performs query on Jboss server. It has JNDI based datasource and looks like this:
public class JNDIBasedDao { DataSource dataSource; public JNDIBasedDao(){ try { InitialContext ic = new InitialContext(); dataSource = (DataSource) ic.lookup("java://bla-bla-bla"); } catch (NamingException e) { e.printStackTrace(); } } public class Manager { public Manager(){} private JNDIBasedDao dao = new JNDIBasedDao(); public void runOperation(){ this.dao.executeInsert(); }
On my laptop I have no Jboss and no ability to connect to this server and want to run Unit testing on HSQLDB.
I want to create BasicDataSource from apache commons based on HSQLDB and inject this object into JNDIBasedDao.
@Mock BasicDataSource dataSource = new BasicDataSource(); @Mock JNDIBasedDao dao = new JNDIBasedDao(); @InjectMocks Manager manager = new Manager(); @Before public void initMocks(){ dataSource.setDriverClassName("org.hsqldb.jdbcDriver"); dataSource.setUrl("jdbc:hsqldb:mem:dannyTest"); dataSource.setUsername("sa"); dataSource.setPassword(""); dataSource.setInitialSize(5); dataSource.setMaxActive(10); dataSource.setPoolPreparedStatements(true); dataSource.setMaxOpenPreparedStatements(10); MockitoAnnotations.initMocks(this); } @Test public void testRunOperartion() { manager.runOperartion(); }
but I'm still getting JNDI error. Can it be done? Please help.
-
Tom Tresansky about 12 yearsIn the latest version, @InjectMocks does field injection also. See: docs.mockito.googlecode.com/hg/latest/org/mockito/…