我有在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错误。可以吗?请帮忙。
答案 0 :(得分:1)
@InjectMocks只会进行二次注射。
在Manager类中更改以下内容
private JNDIBasedDao dao = new JNDIBasedDao();
到
private JNDIBasedDao dao;
并添加
void setDao(JNDOBasedDao dao)
{
this.dao = dao;
}
答案 1 :(得分:1)
您可以创建第二个构造函数并注入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。
答案 2 :(得分:1)
由于您正在使用@Mock
,因此无需通过调用其构造函数来实际实例化这些对象。
而不是:
@Mock
BasicDataSource dataSource = new BasicDataSource();
@Mock
JNDIBasedDao dao = new JNDIBasedDao();
尝试:
@Mock
BasicDataSource dataSource;
@Mock
JNDIBasedDao dao;
让Mockito处理创建这些类的模拟版本。
当然,当你这样做时,你得到这些类的模拟版本,所以在你的dataSource上调用所有这些方法会导致调用默认的Mockito stubbings ......它什么也不做。
不确定为什么你将@Mock
与方法调用合并在一个看起来像你希望得到结果的同一个对象上......
也许单步执行调试器并检查在抛出异常时使用的对象的运行时类。它们可能不是你所期望的那样。