首页 > 解决方案 > SPOCK:如何模拟供应商行为

问题描述

我试图在执行supplierinside时涵盖积极的消极情况CompletableFuture。由于某种原因,模拟值没有在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)
            }
        })

    }

现在,当我调试单元测试用例时,其中的throwable实例.handle总是null. 当我嘲笑PutObjectResult

标签: javaunit-testingjava-8mockitospock

解决方案


因此,我对 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)
            }
        })

    }

推荐阅读