替换Mockito中的DataSource



我有在Jboss服务器上执行查询的代码。它有基于JNDI的数据源,看起来像这样:

    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();
    }

在我的笔记本电脑上,我没有Jboss,也没有能力连接到这个服务器,我想在HSQLDB上运行单元测试。

我想从基于HSQLDB的apache commons创建BasicDataSource,并将此对象注入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();
    }

但我仍然得到JNDI错误。能做到吗?请帮忙。

由于您使用的是@Mock,因此不需要通过调用它们的构造函数来实例化这些对象。

代替:

@Mock
BasicDataSource dataSource = new BasicDataSource();
@Mock 
JNDIBasedDao dao = new JNDIBasedDao();

尝试:

@Mock
BasicDataSource dataSource;
@Mock 
JNDIBasedDao dao;

并让Mockito处理创建这些类的mock版本。

当然,当你这样做的时候,你会得到这些类的Mock版本,所以在dataSource上调用所有这些方法会导致调用默认的Mockito存根。。。它们什么都不做。

不知道为什么要将@Mock与方法调用组合在同一个对象上,看起来会有结果。。。

也许可以遍历调试器,在抛出异常时检查您使用的对象的运行时类。它们可能不是你期望的那样。

@InjectMocks将只执行setter注入。

在Manager类中更改以下内容

private JNDIBasedDao dao = new JNDIBasedDao();

private JNDIBasedDao dao;

并添加

void setDao(JNDOBasedDao dao)
{
   this.dao = dao;
}

您可以创建第二个构造函数并注入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();
    }
  }
  ....
}

现在您可以提供一个模拟的InitialContext,它提供您的DataSource。

最新更新