Java Reactor + Caffeine 缓存 + Mockito = 严格存根参数不匹配

问题描述 投票:0回答:1

我在 Spring-boot 项目中使用 Java Reactor,我需要在其中一个中间步骤中缓存我的数据。它在 Spring Boot 3、Java 17、Junit5 上...

我的缓存服务如下所示:

@Component
public class CachingService {
  private static final int DURATION = 60;

  public Mono<Resource> ofMono(final UUID guid, final Mono<Resource> mono) {
    final String cachingKey = "key";
    final Function<String, Mono<Resource>> monoFn = ofMono(key -> mono);
    return Mono.defer(() -> monoFn.apply(cachingKey));
  }

  private Function<String, Mono<Resource>> ofMono(final Function<String, Mono<Resource>> fn) {
    final AsyncLoadingCache<String, Resource> cache =
        Caffeine.newBuilder()
            .expireAfterWrite(Duration.ofSeconds(DURATION).multipliedBy(2))
            .refreshAfterWrite(Duration.ofSeconds(DURATION))
            .buildAsync((k, e) -> fn.apply(k).subscribeOn(Schedulers.fromExecutor(e)).toFuture());

    return (k) -> Mono.fromFuture(cache.get(k));
  }
}

所以我的目的是缓存“资源”记录的实例,该实例从另一个服务作为 Mono 发布,并将再次在另一个服务中使用。

我正在另一个服务中注入 cachingService 并调用它的方法:

  @Override
  public Mono<Resource> getResourceWithAccess(final UUID guid) {
    final Mono<Boolean> viewAccess = accessService.getViewAccess(guid);

    return viewAccess
        .flatMap(hasAccess -> mapToResource(guid, hasAccess))
        .flatMap(resource -> cachingService.ofMono(guid, Mono.just(resource)));
  }

代码中使用的accessService.getViewAccess和mapToResource:

  Mono<Boolean> accessService.getViewAccess(UUID fileGuid);

  Mono<Resource> mapToResource(
      final UUID guid, final Boolean hasAccess);

我有一个这样的 Mockito 测试:

@Test
  void test() {
    // GIVEN
    ...
    private ResourceWithAccessService service
    @Mock private CachingService cachingService;

    Resource expectedResource = ...
    when(cachingService.ofMono(fileGuid, Mono.just(expectedResource ))).thenReturn(Mono.just(expectedResource ));

    // WHEN
    final Mono<Resource > actualResource =
        service.getResourceWithAccess(fileGuid);

    // THEN
    StepVerifier.create(actualResource).expectNext(expectedResource).verifyComplete();
  }

不幸的是,我收到此错误:

java.lang.AssertionError: expectation ....
actual: onError(org.mockito.exceptions.misusing.PotentialStubbingProblem: 
Strict stubbing argument mismatch. Please check:
 - this invocation of 'ofMono' method:
    cachingService.ofMono(
    98f0b409-20b9-3674-a0e6-eb5048219f2c,
    MonoJust
);
    -> at com...lambda$getResourceWithAccess$1(ResourceWithAccessServiceImp.java:52)
 - has following stubbing(s) with different arguments:
    1. cachingService.ofMono(
    98f0b409-20b9-3674-a0e6-eb5048219f2c,
    MonoJust
);

我不明白问题是什么以及如何解决。我可以通过在存根“cachingService”时为所有参数提供“any()”来解决这个问题,但似乎不正确,因为我不会检查我向该方法提供的参数。

java mockito spring-webflux project-reactor caffeine-cache
1个回答
0
投票

我终于找到了解决方法。通过使用 ArgumentCaptor,我仍然能够检查我的方法是否使用正确的参数调用。

  private void verifyCachingService(final UUID fileGuid, final Resource resource) {
    final ArgumentCaptor<Mono> acMono = ArgumentCaptor.forClass(Mono.class);
    verify(cachingService).ofMono(eq(fileGuid), acMono.capture());
    StepVerifier.create(acMono.getValue()).expectNext(resource).verifyComplete();
  }
© www.soinside.com 2019 - 2024. All rights reserved.