我使用响应式(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/