超级类方法调用中的Mockito NullPointerException



我有以下精简的类(为了简单起见,假设服务接口只有一个overriden方法)。无论我尝试什么,当ServiceImpl调用getSqlSession()时,我总是得到一个NullPointerException。如何覆盖此调用以避免异常?我已经尝试创建一个spyServiceImpl并在方法getSqlSession()上调用when,但我仍然得到了异常。我不想将ServiceImpl.getData()中将List<Object>更改为Map<String,Object>的逻辑放入测试类中,因为如果此实现发生更改,则也需要更改测试代码。有什么建议吗?

public class ServiceImpl extends BaseService implements Service {
    @Autowired
    private ServiceDAO serviceDao;
    @Override
    public Map<String, Object> getData() {
        Map<String,Object> map = new HashMap<String,Object>();
        List<Object> resultSet = service.getData(getSqlSession());
        map.put("Test", resultSet.get(0));
        map.put("Test2", resultSet.get(1));
        return map;
    }
   public void setServiceDao(final ServiceDAO serviceDao) {
     this.serviceDao = serviceDao;
   }
}

基本服务:

public class BaseService {
    @Autowired
    private ApplicationContext context;
    public SqlSession getSqlSession() {
        return (SqlSession)context.getBean("SQL_SESSION");
    }
    public void setContext(ApplicationContext context) {
        this.context=context;
    }
}

DAO

public class ServiceDAO {
    public List<Object> getData(SqlSession sqlSession) {
        return sqlSession.selectList("proc_name");
    }
}

测试类别:

public class ServiceImplTest {
    private Service service;
    @Mock
    private ServiceDAO serviceDao;
    @Before
    public void before() {
        MockitoAnnotations.initMocks(this);
        service = new ServiceImpl();
        service.serviceDao = this.serviceDao;
    }
    @Test
    public void testGetData() {
        Mockito.when(service.getData()).then(new Answer<List<Object>>() {
        @Override
        public List<Object> answer(InvocationOnMock invocation) throws Throwable {
            return serviceDAO.getData(new DefaultSqlSession(null,null));
        }
    });
        service.getData();
    }
}

终于能够在下面的测试类中实现这一点。必须将Service声明从Interface更改为实际的Impl类。不确定是否有办法解决这个问题,因为所有其他尝试都没有奏效。

public class ServiceImplTest {
    @Mock
    private ServiceDAO serviceDAO;
    @Spy
    private ServiceImpl service;
    @Before
    public void before() {
        MockitoAnnotations.initMocks(this);
        //service = new ServiceImpl();
        service.setServiceDAO(this.serviceDAO);
    }
    @Test
    public void testGetData() {
        Mockito.doAnswer(new Answer<SqlSession>(){
            @Override
            public SqlSession answer(InvocationOnMock invocation) throws Throwable {
                return new DefaultSqlSession(null,null);
            }
        }).when(service).getSqlSession();
        Mockito.when(service.getData()).then(new Answer<List<Object>>() {
        @Override
        public List<Object> answer(InvocationOnMock invocation) throws Throwable {
            return serviceDAO.getData(new DefaultSqlSession(null,null));
        }
    });
        service.getData();
    }
}

我相信当您尝试使用服务中的serviceDao:时会发生错误

List<Object> resultSet = service.getData(getSqlSession());

如果您在同一个包中,则需要在服务中注入模拟的serviceDAO:

@Before
public void before() {
    MockitoAnnotations.initMocks(this);
    service = new ServiceImpl();
    service.service = this.serviceDAO;
}

相关内容

  • 没有找到相关文章