【问题标题】:Mockito test iterator return always false on hasNextMockito 测试迭代器在 hasNext 上总是返回 false
【发布时间】:2020-09-06 20:27:33
【问题描述】:

我有这个方法:

    public void executeShadowingCF(String outputPath) throws Exception {
            try{

                Iterator<Fatt0Gdpr> notProcessedGDPRIterator = gdprDAO.getGdprRowCF(em1Fatt0);

                while(notProcessedGDPRIterator.hasNext()){
                    Fatt0Gdpr element = notProcessedGDPRIterator.next();

                    String codiceFiscale = element.getCodFiscale();

                    if(codiceFiscale != null && !codiceFiscale.equalsIgnoreCase("")){
                        //some operation

                    }
                    else{
                        gdprDAO.updateProcessedRow(emFatt0Update, element.getIdTecnico(), "99");
                    }

                }               

            }
            catch(Exception e ){
                log.error(e);
            }
            finally{
                emFatt0.close();
            }
        }

我正在尝试使用 mockito 对其进行测试,但是当我执行测试时,notProcessedGDPRIterator.hasNext() 始终返回 false,因此我无法进入 while 循环。 这是我的测试方法:

       @Test
        public void testExecuteShadowingCF() {    
            try {
                EntityManager em1Fatt0 = Mockito.mock(EntityManager.class);
                EntityManager emFatt0 = Mockito.mock(EntityManager.class);
                Fatt0GdprService service = new Fatt0GdprService();          
                Fatt0GdprDAO fatt0GdprDAO = new Fatt0GdprDAO(); 
                Query queryFind = Mockito.mock(Query.class);
                Iterator<Fatt0Gdpr> mockIterator = Mockito.mock(Iterator.class);
                Mockito.when(
                        emFatt0.createNativeQuery(Mockito.anyString(),
                                eq(Fatt0Gdpr.class))).thenReturn(queryFind);    
                Mockito.when(fatt0GdprDAO.getGdprRowNDG(emFatt0)).thenReturn(mockIterator); 

                Mockito.when(mockIterator.hasNext()).thenReturn(true).thenReturn(false);
                Mockito.when(mockIterator.next()).thenReturn(new Fatt0Gdpr());

                service.setEmFatt0Updater(emFatt0);
                EntityTransaction trxMock = Mockito.mock(EntityTransaction.class);
                Mockito.when(service.getEmFatt0Updater().getTransaction())
                        .thenReturn(trxMock);

                String outputPath = "U:/RTC_U0E7069/fatt0_SRC/SRC/fatt0-gdpr-batch/target/diraliases/BATCHROOT/ITT/out";

                service.executeShadowingCF(outputPath);

            } catch (Exception e) {
                e.printStackTrace();
            }
        }

有人可以帮我解决这个问题吗? 谢谢

【问题讨论】:

  • gdprDAO 的类和getGdprRowCF() 的参数参数是什么?
  • 公共迭代器 getGdprRowCF(EntityManager emFatt0){ StringBuilder nativeQueryBuilder = new StringBuilder(); String nativeQuery = nativeQueryBuilder.append("SELECT * FROM TABLE_GDPR WHERE FLG_ELABORATO = 'N' AND COD_FISCALE 不为空").toString();查询 queryFind = emFatt0.createNativeQuery(nativeQuery,Fatt0Gdpr.class);返回 queryFind.getResultStream().iterator(); }
  • 但是测试目标类中调用getGdprRowCF()的方法不是getGdprRowNDG()

标签: java iterator mockito next


【解决方案1】:

不要模拟迭代器。

您应该只在行为太难以其他方式创建时才使用模拟。来自Wikipedia

如果一个对象具有以下任何特征,则在其位置使用模拟对象可能会很有用:

  • 对象提供不确定的结果(例如当前时间或当前温度);
  • 它具有难以创建或重现的状态(例如网络错误);
  • 速度很慢(例如,一个完整的数据库,必须在测试前初始化);
  • 它尚不存在或可能会改变行为;
  • 它必须包含专门用于测试目的(而不是用于其实际任务)的信息和方法。

迭代器没有任何这些属性(必须):只需让返回迭代器的方法使用Arrays.asList().iterator(),或类似的。

List<Fatt0Gdpr> fakeData = Arrays.asList(new Fatt0Gdpr());
Mockito.when(fatt0GdprDAO.getGdprRowNDG(emFatt0)).thenReturn(fakeData.iterator()); 

【讨论】:

  • 你在嘲笑when(fatt0GdprDAO.getGdprRowNDG(emFatt0)),但你的方法调用getGdprRowCF。这很重要吗?
  • 抱歉正确的方法是 getGdprRowCF 但我总是遇到同样的错误...
  • 好的,但是您显示的代码设置了getGdprRowNDG 的输出。你是复制+粘贴你的测试方法(在这种情况下你是在模拟错误的方法,需要修复代码来调用正确的方法),还是你在这里输入它(在这种情况下你犯了一个转录错误)?
  • 在我的代码中我有正确的方法名称......这不是问题......
【解决方案2】:

我猜你应该模拟 gdprDAO 并定义 getGdprRowCF 的行为并返回 mockIterator

Mockito.when(gdprDAO.getGdprRowCF(em1Fatt0)).thenReturn(mockIterator); 

定义List 并将其作为迭代器而不是mockIterator 发送的最佳实践

List<Fatt0Gdpr> list = new ArrayList<>();
list.add(new Fatt0Gdpr());
Mockito.when(gdprDAO.getGdprRowCF(em1Fatt0)).thenReturn(list.iterator()); 

【讨论】:

  • 有了你的建议,我现在有这个错误:org.mockito.exceptions.misusing.WrongTypeOfReturnValue: Itr cannot be returned by getResultStream() getResultStream() should return Stream
  • 检查方法名称,这就是如何执行此任务的想法
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-04-28
  • 1970-01-01
  • 2015-07-10
  • 2013-03-28
相关资源
最近更新 更多