英文:
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<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);
}
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<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();
}
Does anybody know an elegant way of writing a junit test to test fetching multiple documents from mongodb?
专注分享java语言的经验与见解,让所有开发者获益!
评论