Java 模仿getJdbcTemplate方法
我的场景如下: 我在SampleDao接口中没有Java 模仿getJdbcTemplate方法,java,mockito,junit4,Java,Mockito,Junit4,我的场景如下: 我在SampleDao接口中没有设置器方法,在SampleDaoImpl类中没有直接字段 参考: 你在模仿错误的对象。您正在尝试测试SampleDaoImpl.someMethod(),因此必须创建具体的SampleDaoImpl实例,而不是模拟实例 一旦有了一个具体的实例,就可以调用setJdbcTemplate()并传入一个模拟的JdbcTemplate对象。最后,您可以控制该模拟的行为,以便当someMethod()调用query()时,返回首选数据 例如: public
设置器方法,在SampleDaoImpl类中没有直接字段
参考:
你在模仿错误的对象。您正在尝试测试SampleDaoImpl.someMethod()
,因此必须创建具体的SampleDaoImpl
实例,而不是模拟实例
一旦有了一个具体的实例,就可以调用setJdbcTemplate()
并传入一个模拟的JdbcTemplate
对象。最后,您可以控制该模拟的行为,以便当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.
}
}
公共类MockSampleDao{
//为简洁起见,省略了参数化的内容
@试验
public void testSomeMethod()引发异常{
SampleDaoImpl impl=新的SampleDaoImpl();
JdbcTemplate=mock(JdbcTemplate.class);
List someList=//填充此列表
when(template.query(..).thenReturn(someList);
impl.setJdbcTemplate(模板);
impl.someMethod(param1,param2);
//进一步测试等。
}
}
它应该是这样的(根据要覆盖的查询API调整模拟):
正如我在第一篇文章中提到的,getJdbcTemplate()是不可能的。getJdbcTemplate()与接口SampleDao无关。。。正如@Duncan所提到的,作为一项工作,我已经对SampleDaoImpl进行了模拟。但正在寻找更好的方法。@NamingException可以尝试其他方法-从SampleDaoImpl
扩展并重写getJdbcTemplate
方法。这是因为您的类有不止一个“角色”-它是JdbcDaoSupport
&SampleDao
-如果您在接口中添加方法getDao
将解决您的问题-1:扩展测试类不是正确的方法。@Duncan我认为在某些情况下这样做是正确的。我更新了上面的注释-在本例中,当SampleDao
不提供对doa的访问时-我认为这是一种方法。更新接口将消除扩展测试类的需要。同样在单元测试中,您希望测试受保护的方法(+1),作为我下面所做的工作,类似于u所说的。但为了更好的方法发布@Mock-SampleDaoImpl-sampleDao=new-SampleDaoImpl()@我不明白那句话。你根本不应该模仿SampleDaoImpl
。抱歉,编辑了评论。通过为SampleDaoImple创建对象,我可以直接模拟getJdbcTemplate(),因为它扩展了JdbcDaoSupportclass@NamingException我想这种方法也会奏效。但我总是希望尽可能避免嘲笑我的测试类——乍一看这很混乱。由于使用了方便的setJdbcTemplate()
方法,这种情况完全可以避免。JdbcDaoSupport从何处获取从getJdbcTemplate()返回的值?也许您可以模拟用于生成jdbcTemplate的对象?
@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();
}
}
}
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.
}
}
@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();
}
}