danny.lesnik
danny.lesnik

Reputation: 18639

some help on Mockito

I have the following structure:

public class MyDao{

private JdbcTemplate  jdbcTemplate;
private DataSource dataSource;


public DataSource getDataSource() {
    return dataSource;
}


public void setDataSource(DataSource dataSource) {
    this.dataSource = dataSource;
}

public void setJdbcTemplate(JdbcTemplate jdbcTemplate) {
        this.jdbcTemplate = jdbcTemplate;
    }

    public VCASDao(DataSource dataSource ){
        jdbcTemplate = new JdbcTemplate(dataSource);
    }
}

Some Manager class

 public class MyManager{

MyDao dao = null;
private DataSource dataSource;

public MyManager(){}

    public DataSource getDataSource() {
        return dataSource;
    }

    public void setDataSource(DataSource dataSource) {
        this.dataSource = dataSource;
    } 

   public void someMethod(Object o){
      dao.save(o);
   }
   }
}

and facade class

public class MyFacadeClass{

private MyManager manager;

public MyFacadeClass(){
 manager = new MyManager();
}

public void someFacadeMethod(Object o){
 manager.someMethod(o);
}

}

Now I would like to test it with JUnit and Mockito. My problem is that I don't have JNDI schema and I need to mock JdbcTemplate with DataSource based on HSQLDB.

My mocking looks like this:

@Mock
static BasicDataSource dataSource ;

@Mock
static JdbcTemplate jdbcTemplate ;

@Mock 
MyDao dao;

MyFacadeClass myFacadeClass = new MyFacadeClass();

    @BeforeClass
    public static void init(){
          dataSource = new BasicDataSource();
      dataSource.setDriverClassName("org.hsqldb.jdbcDriver");
          dataSource.setUrl("jdbc:hsqldb:mem:Test");
          dataSource.setUsername("sa");
          dataSource.setPassword("");
          dataSource.setInitialSize(5);
          dataSource.setMaxActive(10);
          dataSource.setPoolPreparedStatements(true);
          dataSource.setMaxOpenPreparedStatements(10);
          jdbcTemplate = new JdbcTemplate(dataSource);
          jdbcTemplate
          .execute("create Some Table");
    }


@Test
public void testSomeFacadeMethod(){
Object o = new Object();
myFacadeClass.someFacadeMethod(o);
}

I'm getting exception in MyManager constructor that JNDI name for "some_DB" does not exist.

I think I have a problem with Mocking general approach. please help.

P.S: I'm not using spring in this project just use JdbcTemplate class for code simplicity.

Update:

I changed my classes but now dao object is null.

Upvotes: 2

Views: 1007

Answers (2)

bric3
bric3

Reputation: 42223

From what you posted, I gather you want to test MyFacadeClass. If that is indeed the case you are mocking the wrong stuff here.

The only interesting relationship is MyFacadeClass -> MyManager. JNDI and JdbcTemplate aren't even visible to MyFacadeClass, why would you make them appear in your test ;)

Here's the direction I would go, while keeping the same architecture :

  1. So in MyFacadeClassTest you should only mock MyManager and inject it in MyFacadeClass, and test the relevant scenarios.

  2. In MyManager, I would advise you to not test JNDI stuff, for example you can create a package visible constructor that directly take a MyDao object. It would be even better to externalize this JNDI stuff in another class, it could be something like MyDaoProvider. Then in MyManagerTest you will test the relevant interaction between MyManager and a MyDao mock.

  3. Finally, you'll want to test MyDao, as the DAO can only be tested correctly with a real database, this means that it will need another system to run. This test is an integration test. You will either run it against the real DB (Oracle, etc.) or an in memory DB (HSQLDB,etc.), in this case you will create a real JdbcTemplate according to your test environment, and you will inject it in the DAO. Also you can not run these tests at all, you'll run business acceptance tests instead.

Hope that helps.

Upvotes: 5

Petar Minchev
Petar Minchev

Reputation: 47373

MyManager shouldn't lookup the datasource. The datasource should be injected into it. This is the Dependency Injection principle. It makes testing easier because you can easily put your own implementation into it(in this case your own datasource).

Another option is to add a getDataSource() method into the MyManager class and then mock it.

Upvotes: 1

Related Questions