Mockito测试迭代器在hasNext时总是返回false。

问题描述 投票:0回答:1

我有这个方法。

    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() return总是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();
            }
        }

谁能帮我解决这个问题? 谢谢

java iterator mockito next
1个回答
1
投票

不要模拟迭代器。

只有当行为太难创建时,你才应该使用mock,否则的话。从 维基百科:

如果一个对象具有以下任何特征,使用一个模拟对象来代替它可能是有用的。

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

迭代器没有这些属性(一定):只要让迭代器返回的方法使用 Arrays.asList().iterator()或类似的。

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

0
投票

我想你应该嘲笑 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()); 
© www.soinside.com 2019 - 2024. All rights reserved.