我有在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。