Mockito FindIterable <文档>

我正在尝试使用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();

        }

朱尼特:


@Test

public 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。


qq_遁去的一_1
浏览 324回答 4
4回答

海绵宝宝撒

正如您正确指出的那样,您将获得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())&nbsp;&nbsp; .thenReturn(true)&nbsp; .thenReturn(true)// do this as many times as you want your loop to traverse&nbsp;.thenReturn(false); // Make sure you return false at the end.when(cursor.next())&nbsp; .thenReturn(doc1)&nbsp; .thenReturn(doc2);&nbsp;这不是一个完整的解决方案。您需要使其适应您的班级。

素胚勾勒不出你

您将返回null在collection.find(...)嘲笑调用:FindIterable<Document> findIterable = null;Mockito.when(collection.find(new Document())).thenReturn(findIterable);因此,该模拟将null在运行时返回。您需要返回一个FindIterable<Document>对象,该对象允许执行代码以测试与关联的对象:for (Document doc : cursorPersonDoc) {&nbsp; &nbsp; emplinfo.setEmplFirstName(doc.getString("firstname"));&nbsp; &nbsp; emplinfo.setEmplLastName(doc.getString("lastname"));&nbsp; &nbsp; break;}return emplinfo;这样,您可以断言该方法已实现其设计目的:设置检索到的名字和姓氏FindIterable<Document>。您可以使用该Mockito.mock()方法来模拟FindIterable<Document>一个Iterable(而used foreach)。此外,为了不打扰嘲笑的各个方法Iterator(hasNext(),next()),可以使你少测试可读,使用List(这也是一个Iterable)来填充DocumentS和委托嘲笑的行为FindIterable.iterator()来List.iterator()。@Testpublic void testGetMetaData() throws Exception {&nbsp; ...&nbsp;&nbsp; // add your document instances&nbsp; final List<Document> documentsMocked = new ArrayList<>();&nbsp; documentsMocked.add(new Document(...));&nbsp; documentsMocked.add(new Document(...));&nbsp; // mock FindIterable<Document>&nbsp; &nbsp;FindIterable<Document> findIterableMocked = (FindIterable<Document>) Mockito.mock(FindIterable.class);&nbsp; // mock the behavior of FindIterable.iterator() by delegating to List.iterator()&nbsp; when(findIterableMocked.iterator()).thenReturn(documentsMocked.iterator());&nbsp; // record a behavior for Collection.find()&nbsp; Mockito.when(collection.find(dbObj)).thenReturn(findIterableMocked);&nbsp; // execute your method to test&nbsp; EmplInfo actualEmplInfo = personDocumentRepo.getMetaData(...);&nbsp; // assert that actualEmplInfo has the expected state&nbsp; 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)

慕森卡

我想pvpkiran用一种通用的方法来模拟DistinctIterable(与FindIterable)来完成答案。注意:为了避免声纳警告,我使用内部类&nbsp; &nbsp; private DistinctIterable<String> mockDistinctIterableString(List<String> resultList) {&nbsp; &nbsp; &nbsp; &nbsp; DistinctIterable<String> iterable = mock(DistinctIterableString.class);&nbsp; &nbsp; &nbsp; &nbsp; MongoCursor cursor = mock(MongoCursor.class);&nbsp; &nbsp; &nbsp; &nbsp; doReturn(cursor)&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; .when(iterable).iterator();&nbsp; &nbsp; &nbsp; &nbsp; OngoingStubbing<Boolean> whenHasNext = when(cursor.hasNext());&nbsp; &nbsp; &nbsp; &nbsp; for (String resultEntry : resultList) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; whenHasNext = whenHasNext.thenReturn(true);&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; whenHasNext.thenReturn(false);&nbsp; &nbsp; &nbsp; &nbsp; if (CollectionUtils.isEmpty(resultList)) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return iterable;&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; OngoingStubbing<Object> whenNext = when(cursor.next());&nbsp; &nbsp; &nbsp; &nbsp; for (String resultEntry : resultList) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; whenNext = whenNext.thenReturn(resultEntry);&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; return iterable;&nbsp; &nbsp; }&nbsp; &nbsp; public interface DistinctIterableString extends com.mongodb.client.DistinctIterable<String> {&nbsp; &nbsp; }用:&nbsp; &nbsp; &nbsp; &nbsp; doReturn(mockDistinctIterableString(asList(&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; "entry1",&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; "entry2",&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; "lastEntry"&nbsp; &nbsp; &nbsp; &nbsp; )))&nbsp; &nbsp; &nbsp; &nbsp; .when(myRepository)&nbsp; &nbsp; &nbsp; &nbsp; .myMongoDistinctQuery();
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Java