【问题标题】:Mockito NullPointerException From Super Class Method Call来自超类方法调用的 Mockito NullPointerException
【发布时间】:2016-04-05 23:05:37
【问题描述】:

我有以下精简的类(为了简单起见,我们假设 Service 接口只有一个覆盖的方法)。无论我尝试什么,当 ServiceImpl 调用 getSqlSession() 时,我总是会收到 NullPointerException 。如何覆盖此调用以避免异常?我尝试创建一个间谍 ServiceImpl 并在方法 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();

    }
}

【问题讨论】:

  • 可能是@Spy注解会有所帮助
  • 终于可以使用间谍来完成这项工作,谢谢
  • 感谢很高兴它有帮助

标签: java spring mockito junit4


【解决方案1】:

终于能够在下面的测试类中使用它。必须将接口中的Service 声明更改为实际的 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();

    }

}

【讨论】:

    【解决方案2】:

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

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

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

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

    【讨论】:

    • 我假设你的意思是service.serviceDAO = this.serviceDAO;,我也试过了。没用。
    • 不,我的意思是你的 ServiceImpl 中的“service.service”,道被称为“服务”,我相信这个类是 null ?你到底从哪里得到异常?
    • 对不起,你是对的。编辑了上面的代码以澄清,并添加了您的更改(以表明我已经尝试过)。但对我来说,我仍然遇到异常。在service.getData(getSqlSession()) 的电话下,我每次都在您所在的位置得到异常
    猜你喜欢
    • 2018-06-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-02-03
    • 1970-01-01
    相关资源
    最近更新 更多