亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

Mockito FindIterable <文檔>

Mockito FindIterable <文檔>

qq_遁去的一_1 2021-04-06 17:14:18
我正在嘗試使用Mockito框架為以下方法編寫JUnit測試用例。方法:public EmplInfo getMetaData(String objectId) {        objectId = new StringBuffer(objectId).reverse().toString();        try{            BasicDBObject whereClauseCondition = getMetaDataWhereClause(objectId);            EmplInfo emplinfo= new EmplInfo ();            emplinfo.set_id(objectId);            FindIterable<Document> cursorPersonDoc = personDocCollection.find(whereClauseCondition);            for (Document doc : cursorPersonDoc) {                emplinfo.setEmplFirstName(doc.getString("firstname"));                emplinfo.setEmplLastName(doc.getString("lastname"));                break;            }            return emplinfo;        }catch(Exception e){         e.printstacktrace();        }朱尼特:@Testpublic void testGetMetaData() throws Exception {    String docObjectId = "f2da8044b29f2e0a35c0a2b5";    BasicDBObject dbObj = personDocumentRepo.getMetaDataWhereClause(docObjectId);    FindIterable<Document> findIterable = null;    Mockito.when(collection.find(dbObj)).thenReturn(findIterable);    personDocumentRepo.getMetaData(docObjectId);}在“ personDocumentRepo.getMetaData(docObjectId)”中獲得空值期望,因為“返回”為NULL的findIterable。不確定如何將虛擬/測試值分配給findIterable。
查看完整描述

4 回答

?
海綿寶寶撒

TA貢獻1809條經驗 獲得超8個贊

正如您正確指出的那樣,您將獲得NPE,因為FindIterable為null。您需要模擬它。模擬

它并不是那么簡單,因為它使用MongoCursor(又擴展了Iterator),因此您需要模擬內部使用的某些方法。


在遍歷Iter的某些方法時


我相信你必須做這樣的事情。


FindIterable iterable = mock(FindIterable.class);

MongoCursor cursor = mock(MongoCursor.class);


Document doc1= //create dummy document;

Document doc2= //create dummy document;


when(collection.find(dbObj)).thenReturn(iterable);


when(iterable.iterator()).thenReturn(cursor);

when(cursor.hasNext()) 

  .thenReturn(true)

  .thenReturn(true)// do this as many times as you want your loop to traverse

 .thenReturn(false); // Make sure you return false at the end.

when(cursor.next())

  .thenReturn(doc1)

  .thenReturn(doc2); 

這不是一個完整的解決方案。您需要使其適應您的班級。


查看完整回答
反對 回復 2021-04-21
?
素胚勾勒不出你

TA貢獻1827條經驗 獲得超9個贊

您將返回null在collection.find(...)嘲笑調用:


FindIterable<Document> findIterable = null;

Mockito.when(collection.find(new Document())).thenReturn(findIterable);

因此,該模擬將null在運行時返回。您需要返回一個FindIterable<Document>對象,該對象允許執行代碼以測試與關聯的對象:


for (Document doc : cursorPersonDoc) {

    emplinfo.setEmplFirstName(doc.getString("firstname"));

    emplinfo.setEmplLastName(doc.getString("lastname"));

    break;

}

return emplinfo;

這樣,您可以斷言該方法已實現其設計目的:設置檢索到的名字和姓氏FindIterable<Document>。


您可以使用該Mockito.mock()方法來模擬FindIterable<Document>一個Iterable(而used foreach)。

此外,為了不打擾嘲笑的各個方法Iterator(hasNext(),next()),可以使你少測試可讀,使用List(這也是一個Iterable)來填充DocumentS和委托嘲笑的行為FindIterable.iterator()來List.iterator()。


@Test

public void testGetMetaData() throws Exception {

  ... 

  // add your document instances

  final List<Document> documentsMocked = new ArrayList<>();

  documentsMocked.add(new Document(...));

  documentsMocked.add(new Document(...));


  // mock FindIterable<Document>

   FindIterable<Document> findIterableMocked = (FindIterable<Document>) Mockito.mock(FindIterable.class);


  // mock the behavior of FindIterable.iterator() by delegating to List.iterator()

  when(findIterableMocked.iterator()).thenReturn(documentsMocked.iterator());


  // record a behavior for Collection.find()

  Mockito.when(collection.find(dbObj)).thenReturn(findIterableMocked);


  // execute your method to test

  EmplInfo actualEmplInfo = personDocumentRepo.getMetaData(...);


  // assert that actualEmplInfo has the expected state

  Assert(...);


}

我要補充一點,這樣的模擬可能不會起作用:


Mockito.when(collection.find(new Document())).thenReturn(findIterable);

僅當記錄中的參數(以表示equals())與運行時通過測試的方法傳遞的參數匹配時,Mockito才會攔截并替換在模擬程序上調用的方法的行為。

在運行時,以這種方式構建參數:


BasicDBObject whereClauseCondition = getMetaDataWhereClause(objectId);

EmplInfo emplinfo= new EmplInfo ();

emplinfo.set_id(objectId);

因此,模擬錄制中的自變量應等于上面定義的自變量。

請注意,如果equals()參數類不能被覆蓋/覆蓋,則可以采用以下解決方法:


將對象作為參數傳遞給方法進行測試(需要進行一些重構)。在這種情況下,模擬參數和運行時在測試方法中傳遞的引用必須相等,因為它們引用相同的對象


將任何給定類型的對象與匹配Mockito.any(Class<T>)。通常是最簡單的方法,但不是最可靠的


返回Answer而不是要返回的值。那是用Mockito.when(...).then(Answer)代替Mockito.when(...).thenReturn(valuetoReturn)


查看完整回答
反對 回復 2021-04-21
?
慕森卡

TA貢獻1806條經驗 獲得超8個贊

我想pvpkiran用一種通用的方法來模擬DistinctIterable(與FindIterable)來完成答案。


注意:為了避免聲納警告,我使用內部類



    private DistinctIterable<String> mockDistinctIterableString(List<String> resultList) {

        DistinctIterable<String> iterable = mock(DistinctIterableString.class);

        MongoCursor cursor = mock(MongoCursor.class);

        doReturn(cursor)

                .when(iterable).iterator();

        OngoingStubbing<Boolean> whenHasNext = when(cursor.hasNext());

        for (String resultEntry : resultList) {

            whenHasNext = whenHasNext.thenReturn(true);

        }

        whenHasNext.thenReturn(false);

        if (CollectionUtils.isEmpty(resultList)) {

            return iterable;

        }

        OngoingStubbing<Object> whenNext = when(cursor.next());

        for (String resultEntry : resultList) {

            whenNext = whenNext.thenReturn(resultEntry);

        }

        return iterable;

    }


    public interface DistinctIterableString extends com.mongodb.client.DistinctIterable<String> {

    }

用:


        doReturn(mockDistinctIterableString(asList(

                "entry1",

                "entry2",

                "lastEntry"

        )))

        .when(myRepository)

        .myMongoDistinctQuery();


查看完整回答
反對 回復 2021-04-21
  • 4 回答
  • 0 關注
  • 400 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號