java - 使用 spock 对 Spring Cloud Gateway 过滤器进行单元测试

标签 java unit-testing groovy spock spring-cloud-gateway

我使用响应式(Reactive)全局过滤器在网关响应中添加 cookie,如下所示:

chain.filter(exchange).then(<a mono relevant to response>)

当我尝试使用 spock 进行测试时,然后方法不会从 stub Mono 中调用。

过滤器本身:

@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
    return chain.filter(exchange)
            .then(refreshCookiesMono(exchange));
}

private Mono<Void> refreshCookiesMono(ServerWebExchange exchange) {
    return Mono.fromRunnable(() -> {
        //interactions with *exchange* and *chain*
    });
}

尽管最终为 0 * _,但该测试还是通过了:

@Subject
CookieFilter cookieFilter = new CookieFilter(cookieHelper)
...
ServerWebExchange exchange = Mock ServerWebExchange
GatewayFilterChain chain = Mock GatewayFilterChain
Mono<Void> mono = Mock Mono

...

def "cookieFilter refreshes the cookie with a new value"() {
    given:

    when:
    cookieFilter.filter(exchange, chain)

    then:
    1 * chain.filter(exchange) >> mono
    0 * _
}

但在代码中,我从 .filter 方法返回的单声道调用 .then

为什么不考虑mono.then()?当然,当我尝试测试所有底层逻辑时 - spock 找不到交互。

最佳答案

chain.filter(exchange) 返回您模拟的 mono 实例。

您没有对该模拟指定任何期望(我相信这就是您问题的答案),因此测试并没有真正检查过滤器,它只检查是否有是对chain.filter(exchange)的一次调用。

此外,Spock 除了 Mock 之外还支持 Stub,与许多其他框架不同的是,它们之间存在差异:

模拟“更重”,您可以对它们进行验证(在“then” block 中), stub 更加“轻量级”,您通常可以在“given” block 中指定对它们的期望。 通常,如果您想模拟某些交互并将测试基于围绕此交互进行管理的协议(protocol),则可以使用模拟,在其他情况下, stub 更可取。

关于java - 使用 spock 对 Spring Cloud Gateway 过滤器进行单元测试,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58787680/

相关文章:

java - 通过 Spring 将属性文件公开给 Java

java - 尝试用随机数创建 for 循环?

ruby - 我如何在测试中模拟 %x?

groovy - 调用fileTree(Object,Closure)签名时遇到问题

作为 Unix 服务运行的 Java

java - Android 明文

python - 在 Django 中测试特定的应用程序

ios - 如何测试自定义 UINavigationController 行为

bash - 从名称获取 AWS EMR 集群 ID

java - grails 中面向方面的编程问题。切入点方法未执行