我是Reactor的新手,我想知道实现这种简单逻辑的正确方法是什么。我想比较项目的两个集合,如果项目匹配,我想将它们添加到Mono 。如果项目相等或项目是其他项目的父项,则匹配它们。
我的测试方法有时会通过,而有时会失败,原因是Mono 中的项目数不正确。我不知道是什么问题。似乎当我使用此单一测试方法为类运行junit测试时,它通过了。但是,当我在同一个类中放置其他测试方法以测试不同的输入/输出时,有时会失败,并且列表中的项目不正确。好像测试方法快完成了一样,才用所有添加的项目更新列表。
package test;
import static org.assertj.core.api.Assertions.assertThat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import org.junit.Test;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;
import reactor.test.StepVerifier;
public class ReactorBasicsTests {
@Test
public void testMatching() {
Mono<List<String>> matched = matching(
Arrays.asList("fruit", "vegetable", "meat"),
Arrays.asList("apple", "orange", "carrot", "meat"));
StepVerifier.create(matched)
.consumeNextWith(list -> {
assertThat(list).containsExactlyInAnyOrder(
"fruit+apple", "fruit+orange", "vegetable+carrot", "meat+meat");
})
.expectComplete()
.verify();
}
/**
* Items are matched when:
* 1) they are equal (meat equals to meat)
* 2) item is parent of child item (fruit is parent of apple)
*/
public Mono<List<String>> matching(List<String> list1, List<String> list2) {
Flux<String> items1 = Flux.fromIterable(list1);
Flux<String> items2 = Flux.fromIterable(list2);
List<String> matched = new ArrayList<>();
return items1
.flatMap(item1 -> items2
.flatMap(item2 -> {
// Check if item1 is equal to item2
Mono<Void> isEqual = Mono.fromSupplier(() -> {
if (item1.equals(item2)) {
matched.add(item1 + "+" + item2);
}
return null; // I have to return something to compile the code
}).then();
// Check if item1 is parent of item2
Mono<Void> isParent = this.getParents(item2).hasElement(item1)
.flatMap(booleanValue -> {
if (booleanValue) {
matched.add(item1 + "+" + item2);
}
return Mono.empty();
});
return isEqual.then(isParent).then();
})
).then(Flux.fromIterable(matched).collectList());
}
/** This method simulates reactive database repository request that returns Flux<String> **/
public Flux<String> getParents(String item) {
if (item.equals("apple") || item.equals("orange")) return Flux.just("fruit", "food");
else if (item.equals("carrot")) return Flux.just("vegetable", "food");
return Flux.empty();
}
}