如何在java中使用junit mockito处理依赖于抽象方法的测试类

如何在java中使用junit mockito处理依赖于抽象方法的测试类,java,unit-testing,junit,mockito,spring-test,Java,Unit Testing,Junit,Mockito,Spring Test,我不熟悉在java中使用mockito进行junit测试。我曾一度陷入困境。 我有一个抽象类AbstractA需要测试。 AbstractA的实现如下 public abstract class AbstractA implements ADao { @Autowired NamedParameterJdbcTemplate jdbcTemplate; @Override public List<String> getColumns(Set<St

我不熟悉在java中使用mockito进行junit测试。我曾一度陷入困境。 我有一个抽象类AbstractA需要测试。 AbstractA的实现如下

public abstract class AbstractA implements ADao {
    @Autowired
    NamedParameterJdbcTemplate jdbcTemplate;
    @Override
    public List<String> getColumns(Set<String> ids) {
        String sql = query();
        Map<String, Object> paramMap = new HashMap<>();
        paramMap.put("ids", ids);
        return jdbcTemplate.query(sql, paramMap, rowMapper());
    }
    abstract protected String query();
    abstract protected AbstractIpRowMapper rowMapper();
}
公共抽象类AbstractA实现ADao{
@自动连线
NamedParameterJdbcTemplate jdbcTemplate;
@凌驾
公共列表getColumns(设置ID){
字符串sql=query();
Map paramMap=新的HashMap();
paramMap.put(“ids”,ids);
返回jdbcTemplate.query(sql,paramMap,rowMapper());
}
抽象保护字符串查询();
抽象受保护的AbstractIpRowMapper rowMapper();
}
上面的一个测试类被删除

public class AbsractATest {
    @InjectMocks 
    AbsractA abstractA;
    @Mock
    NamedParameterJdbcTemplate jdbcTemplate;

    @Mock AbstractIpRowMapper abstractIpRowMapper;
    @Before
    public void setUp() throws IOException, SQLException {
        abstractA=Mockito.mock(AbsractA.class, Mockito.CALLS_REAL_METHODS);
        jdbcTemplate=mock(NamedParameterJdbcTemplate.class);

        List<String> idsinput=new ArrayList<String>();
        idsinput.add("123");
        idsinput.add("124");
        idsinput.add("125");

        Set<String> ids=new LinkedHashSet<String>();
        ids.add("123");
        ids.add("124");
        ids.add("125");

        Map<String, Object> paramMap = new HashMap<>();
        paramMap.put("ids", ids);

        String query="select ids from tableA where ids=:ids";
        when(abstractA.query()).thenReturn(query);
        when(jdbcTemplate.query(query, paramMap,rowMapper())).thenReturn(idsinput);
        org.springframework.test.util.ReflectionTestUtils.setField(abstractA, "jdbcTemplate", jdbcTemplate);
    }

protected AbstractIpRowMapper rowMapper() {
    return absractIpRowmapper;
}
But after running this test case I am getting empty value for 
abstractA.getColumns();
公共类abstractest{
@注射模拟
抽象提取物;
@嘲弄
NamedParameterJdbcTemplate jdbcTemplate;
@模拟AbstractIpRowMapper AbstractIpRowMapper;
@以前
public void setUp()引发IOException、SQLException{
abstractA=Mockito.mock(AbsractA.class,Mockito.CALLS\u REAL\u方法);
jdbcTemplate=mock(NamedParameterJdbcTemplate.class);
List idsinput=new ArrayList();
idsinput.add(“123”);
idsinput.add(“124”);
idsinput.add(“125”);
Set id=new LinkedHashSet();
同上,添加(“123”);
同上,添加(“124”);
同上,添加(“125”);
Map paramMap=新的HashMap();
paramMap.put(“ids”,ids);
String query=“从表A中选择ID,其中ID=:ids”;
when(abstractA.query())。然后return(query);
当(jdbcTemplate.query(query,paramMap,rowMapper()).thenReturn(idsinput);
org.springframework.test.util.ReflectionTestUtils.setField(abstractA,“jdbcTemplate”,jdbcTemplate);
}
受保护的抽象行映射器行映射器(){
返回航母;
}
但是在运行这个测试用例之后,我得到的是空值
抽象a.getColumns();

请帮助我理解在上述情况下需要做什么。

运行doCallRealMethod().when(abstractA).getColumns();在单元测试中运行doCallRealMethod().when(abstractA).getColumns();在单元测试中

您不需要测试抽象类tdd对抽象类一无所知,将其设置为普通类,并且只有您与两个或多个类有相同的代码重复将其提升为抽象类,该类的测试将不会更改。指定sql查询字符串和IPRowMapper作为构造函数参数,这将简化并使您的第二,您不需要为测试设置如此复杂的设置,您只需要验证交互,而不需要返回值,只需验证
NamedParameterJdbcTemplate
mock,传递给它的值是什么。

您不需要测试抽象类tdd,它对抽象类一无所知,使它成为普通类,只有您有相同的代码d与两个或多个类的复制将其提升为抽象类,该类的测试将不会更改。指定sql查询字符串和IPRowMapper作为构造函数参数,这将简化并使您的代码更干净。其次,您不需要为测试设置如此复杂的设置,您只需验证交互,而不需要返回值,只需验证
NamedParameterJdbcTemplate
mock,传递给它的值是什么。

谢谢你的回复,但我没有得到确切的答案。请详细说明。我想你的意思是说直接给输入我想要测试的方法调用。但是我认为它不是在测试,如果你已经为该方法调用返回了相同的输出,那么测试用例将永远不会失败。不,是的你不是在嘲笑响应,只是告诉Mockito在测试时实际调用该方法。请跟踪评论谢谢回复,但我没有得到确切的答案。请详细说明。我想你的意思是说直接输入我想要测试的方法调用。但如果你已经返回相同的方法,我认为这不是测试方法调用的输出,那么测试用例将永远不会失败。不,您不是在模拟响应,只是告诉Mockito在测试时实际调用该方法。请跟踪注释