我的场景如下:
我在SampleDao接口中有no setter methods
,在SampleDaoImpl类中有no direct field
reference:如何模拟getJdbcTemplate().queryForObject()?
public interface SampleDao {
// some methods
}
public class SampleDaoImpl extends JdbcDaoSupport implements SampleDao {
// implementation of some methods
public String someMethod(String param1, String param2){
// .....//
List<String> data = getJdbcTemplate().query(.....); // -> getJdbcTemplate() is the method of JdbcDaoSupport to get JdbcTemplate
}
}
我想模拟getJdbcTemplate().query(.....)
的结果,其中getJdbcTemplate()
是由SampleDaoImpl
扩展的JdbcDaoSupport
类,而不是由SampleDao
扩展的where。
我的测试用例如下:
创建SampleDaoImpl的对象并分配给SampleDao
@RunWith(Parameterized.class)
public class MockSampleDao {
String param1 = "", param2 = "";
@Mock
SampleDao sampleDao = new SampleDaoImpl();
public MockSampleDao(String param1, String param2) {
super();
this.param1 = param1;
this.param2 = param2;
}
@Parameterized.Parameters
public static Collection primeNumbers() {
return Arrays.asList(new Object[][] {
{ "test1", "test1" },
{ "test2", "test2" }
});
}
@Test
public void testSomeMethod(){
try {
// HOW TO MOCK THE RESULT FROM getJdbcTemplate().query() HERE
sampleDao.someMethod(param1, param2);
} catch (Exception e) {
e.printStackTrace();
}
}
}
您在嘲笑错误的对象。您正在尝试测试SampleDaoImpl.someMethod()
,因此必须创建一个具体的SampleDaoImpl
实例,而不是模拟实例。
一旦有了一个具体的实例,就可以调用setJdbcTemplate()
并传入一个模拟的JdbcTemplate
对象。最后,您可以控制mock的行为,以便在someMethod()
调用query()
时,返回您的首选数据。
例如:
public class MockSampleDao {
// parameterized stuff omitted for brevity
@Test
public void testSomeMethod() throws Exception {
SampleDaoImpl impl = new SampleDaoImpl();
JdbcTemplate template = mock(JdbcTemplate.class);
List<String> someList = // populate this list
when(template.query(....)).thenReturn(someList);
impl.setJdbcTemplate(template);
impl.someMethod(param1, param2);
// further testing etc.
}
}
应该是这样的(根据您想要覆盖的JdbcTemplate的API查询来调整mock):
@RunWith(Parameterized.class)
public class MockSampleDao extends SampleDaoImpl{
JdbcTemplate jdbcTemplate = mock(JdbcTemplate.class);
@Override
protected JdbcTemplate getJdbcTemplate(){
return jdbcTemplate;
}
@Test
public void testSomeMethod(){
try {
when(jdbcTemplate.query(/* put here the api that you want to overload*/)).
thenReturn(/* the mock output that you want */);
sampleDao.someMethod(param1, param2);
} catch (Exception e) {
e.printStackTrace();
}
}