如何在响应式Mongo驱动程序中模拟FindPublisher

huangapple 未分类评论44阅读模式
英文:

How to mock FindPublisher in reactive mongo driver

问题

我正在使用Mongo Reactive Driver和Java中的ReactiveStreams库编写一个应用程序。

我有以下的DAO代码:

@Override
public Flux<ContentVersion> findBySearch(String appKey, ContentVersionSearchRequest request, Pager pager) {
    final var searchResultsPublisher = mongoClient.getDatabase(appKey)
            .getCollection(COLLECTION_CONTENT_VERSION, ContentVersion.class)
            .find(prepareSearchFilter(request))
            .sort(orderBy(ascending(FIELD_VERSION_STATUS_ORDER), descending(FIELD_UPDATE_DATE)))
            .skip(pager.getSkip())
            .limit(pager.getMax());
    return Flux.from(searchResultsPublisher);
}

在Junit测试中,我模拟了MongoClient、MongoDatabase和MongoCollection,但最终MongoCollection返回了一个FindPublisher,我不知道如何正确地模拟它。

我已经成功编写了一个单元测试,通过模拟subscribe方法,如下所示。但是我觉得这不太对。

@Mock
private MongoClient mongoClient;

@Mock
private MongoDatabase database;

@Mock
private MongoCollection<ContentVersion> collection;

@Mock
private FindPublisher<ContentVersion> findPublisher;

@Mock
private UpdateResult updateResult;

@InjectMocks
private ContentVersionDaoImpl contentVersionDao;

@BeforeEach
void initCommonMocks() {
    when(mongoClient.getDatabase("ddpApp")).thenReturn(database);
    when(database.getCollection(MongoConstants.COLLECTION_CONTENT_VERSION, ContentVersion.class)).thenReturn(collection);
    when(collection.find(any(Bson.class))).thenReturn(findPublisher);
    when(collection.find(any(Document.class))).thenReturn(findPublisher);
    when(findPublisher.limit(anyInt())).thenReturn(findPublisher);
    when(findPublisher.skip(anyInt())).thenReturn(findPublisher);
    when(findPublisher.sort(any())).thenReturn(findPublisher);
}

@Test
void shouldFindBySearch() {
    final var contentVersion1 = new ContentVersion();
    final var contentVersion2 = new ContentVersion();

    final var testPublisher = TestPublisher.<ContentVersion>createCold()
            .emit(contentVersion1, contentVersion2);

    doAnswer(invocation -> {
        testPublisher.subscribe(invocation.getArgument(0, Subscriber.class));
        return null;
    }).when(findPublisher).subscribe(any());

    final var searchFlux = contentVersionDao
            .findBySearch("ddpApp", new ContentVersionSearchRequest(null, null, null), new Pager(1, 10));

    StepVerifier.create(searchFlux)
            .expectNext(contentVersion1)
            .expectNext(contentVersion2)
            .expectComplete()
            .verify();
}

有人知道一种优雅的方法来编写一个Junit测试,以测试从mongodb中获取多个文档吗?

英文:

I'm writing an application using mongo reactive driver and reactivestreams library in Java.

I have the following DAO code:

@Override
public Flux&lt;ContentVersion&gt; findBySearch(String appKey, ContentVersionSearchRequest request, Pager pager) {
    final var searchResultsPublisher = mongoClient.getDatabase(appKey)
            .getCollection(COLLECTION_CONTENT_VERSION, ContentVersion.class)
            .find(prepareSearchFilter(request))
            .sort(orderBy(ascending(FIELD_VERSION_STATUS_ORDER), descending(FIELD_UPDATE_DATE)))
            .skip(pager.getSkip())
            .limit(pager.getMax());
    return Flux.from(searchResultsPublisher);
}

In junit tests, I mock MongoClient, MongoDatabase, MongoCollection but finally MongoCollection returns a FindPublisher and I do not know how to mock it correctly.

I have successfully written a unit test by mocking subscribe method as follows. However this does not seem right to me.

@Mock
private MongoClient mongoClient;

@Mock
private MongoDatabase database;

@Mock
private MongoCollection&lt;ContentVersion&gt; collection;

@Mock
private FindPublisher&lt;ContentVersion&gt; findPublisher;

@Mock
private UpdateResult updateResult;

@InjectMocks
private ContentVersionDaoImpl contentVersionDao;

@BeforeEach
void initCommonMocks() {
    when(mongoClient.getDatabase(&quot;ddpApp&quot;)).thenReturn(database);
    when(database.getCollection(MongoConstants.COLLECTION_CONTENT_VERSION, ContentVersion.class)).thenReturn(collection);
    when(collection.find(any(Bson.class))).thenReturn(findPublisher);
    when(collection.find(any(Document.class))).thenReturn(findPublisher);
    when(findPublisher.limit(anyInt())).thenReturn(findPublisher);
    when(findPublisher.skip(anyInt())).thenReturn(findPublisher);
    when(findPublisher.sort(any())).thenReturn(findPublisher);
}

@Test
void shouldFindBySearch() {
    final var contentVersion1 = new ContentVersion();
    final var contentVersion2 = new ContentVersion();

    final var testPublisher = TestPublisher.&lt;ContentVersion&gt;createCold()
            .emit(contentVersion1, contentVersion2);

    doAnswer(invocation -&gt; {
        testPublisher.subscribe(invocation.getArgument(0, Subscriber.class));
        return null;
    }).when(findPublisher).subscribe(any());

    final var searchFlux = contentVersionDao
            .findBySearch(&quot;ddpApp&quot;, new ContentVersionSearchRequest(null, null, null), new Pager(1, 10));

    StepVerifier.create(searchFlux)
            .expectNext(contentVersion1)
            .expectNext(contentVersion2)
            .expectComplete()
            .verify();
}

Does anybody know an elegant way of writing a junit test to test fetching multiple documents from mongodb?

huangapple
  • 本文由 发表于 2020年4月6日 21:25:38
  • 转载请务必保留本文链接:https://java.coder-hub.com/61060894.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定