【问题标题】:SPOCK: How to mock supplier behaviorSPOCK:如何模拟供应商行为
【发布时间】:2019-08-31 14:54:45
【问题描述】:

CompletableFuture 内部执行supplier 时,我试图掩盖积极的消极情况。由于某种原因,模拟值没有在supplier 中传递。我的单元测试用例是使用 spock 框架编写的,由于我对这个框架不是很熟悉,所以我不确定我在模拟时弄错了,或者我缺少供应商模拟的东西。

被测代码:

CompletableFuture
    .supplyAsync(() -> s3Service.upload(bucket, key, file), executor)
    .handle(((putObjectResult, throwable) -> {
        if (throwable != null) {
            CustomRuntimeException exception = (CustomRuntimeException) throwable;
            log.error(exception);
        }
        return putObjectResult;
    }))
    .thenAccept(putObjectResult -> {
        if (putObjectResult != null) {
             FileUtils.deleteQuietly(file);
             log.debug("Deleted file {}", file.getName());
        }
    });

Spock 测试代码:

@SpringBean
private S3Service s3service = Mock()

def "failed to upload article into s3"() {
    given: "mock the s3 service to throw CustomRuntimeException"
    s3Service.upload(_, _, _) >> {

        CompletableFuture<PutObjectResult> exception = new CompletableFuture<>();
        exception.completeExceptionally(new CustomRuntimeException())
        exception.exceptionally(new Function<Throwable, PutObjectResult>() {
            @Override
            PutObjectResult apply(Throwable throwable) {
                throw new CompletionException(throwable)
            }
        })

    }

现在,当我调试单元测试用例时,.handle 中的 throwable 实例始终为 null。当我模拟 PutObjectResult

时也会发生同样的情况

【问题讨论】:

  • 你能提供更多代码吗?最好是MCVE
  • @LeonardBrünings 谢谢。但最终设法解决了问题。

标签: java unit-testing java-8 mockito spock


【解决方案1】:

看来我对 given 和 when 的理解与 Mockito 框架不同。 我已将我的s3Service.upload(_, _, _) 放在then 部分中,并且文本案例按预期工作。所以最终的代码是:

@SpringBean
private S3Service s3service = Mock()

def "failed to upload article into s3"() {
    given: "mock the s3 service to throw CustomRuntimeException"
    // given conditions
    when: "check here the with the actual beans"
    // actual bean calls
    then: "mention your mocks and calls"
    1 * s3Service.upload(_, _, _) >> {

        CompletableFuture<PutObjectResult> exception = new CompletableFuture<>();
        exception.completeExceptionally(new CustomRuntimeException())
        exception.exceptionally(new Function<Throwable, PutObjectResult>() {
            @Override
            PutObjectResult apply(Throwable throwable) {
                throw new CompletionException(throwable)
            }
        })

    }

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-04-26
    • 1970-01-01
    • 1970-01-01
    • 2017-02-22
    • 2015-06-19
    • 1970-01-01
    • 2011-01-10
    相关资源
    最近更新 更多