Search code examples
javajunitmockingjndimockito

Replacing DataSource in Mockito


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.


Solution

  • 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.