我有以下结构:
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);
}
}
一些经理类
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);
}
}
}
和门面课
public class MyFacadeClass{
private MyManager manager;
public MyFacadeClass(){
manager = new MyManager();
}
public void someFacadeMethod(Object o){
manager.someMethod(o);
}
}
现在我想用JUnit和Mockito测试它。我的问题是我没有JNDI模式,我需要使用基于HSQLDB的DataSource来模拟JdbcTemplate。
我的嘲笑看起来像这样:
@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);
}
我在MyManager构造函数中遇到异常,即“some_DB”的JNDI名称不存在。
我认为我对Mocking的一般方法有疑问。请帮忙。
P.S:我在这个项目中没有使用spring只是使用JdbcTemplate类来简化代码。
更新:
我改变了我的类,但现在dao对象为null。
答案 0 :(得分:5)
根据您发布的内容,我知道您要测试MyFacadeClass
。如果情况确实如此,那么你在这里嘲笑错误的东西。
唯一有趣的关系是MyFacadeClass
- > MyManager
。 MyFacadeClass
甚至看不到JNDI和JdbcTemplate,为什么要让它们出现在你的测试中;)
这是我要去的方向,同时保持相同的架构:
因此,在MyFacadeClassTest
中,您只应模拟MyManager
并将其注入MyFacadeClass
,并测试相关方案。
在MyManager
中,我建议你不要测试JNDI的东西,例如你可以创建一个直接接受MyDao
对象的包可见构造函数。将这个JNDI内容外部化到另一个类中会更好,它可能类似于MyDaoProvider
。
然后在MyManagerTest
中,您将测试MyManager
和MyDao
模拟之间的相关互动。
最后,您需要测试MyDao
,因为DAO只能通过真实数据库正确测试,这意味着它需要另一个系统才能运行。该测试是集成测试。您将针对真实数据库(Oracle等)或内存数据库(HSQLDB等)运行它,在这种情况下,您将根据您的测试环境创建一个真正的JdbcTemplate,并将它注入到DAO中。此外,您根本无法运行这些测试,而是运行业务验收测试。
希望有所帮助。
答案 1 :(得分:1)
MyManager
不应该查找数据源。应该将数据源注入其中。这是Dependency Injection
原则。它使测试更容易,因为您可以轻松地将自己的实现放入其中(在这种情况下是您自己的数据源)。
另一种选择是将getDataSource()
方法添加到MyManager
类中,然后模拟它。