I'm adding cookies in gateway response using reactive global filters as:
chain.filter(exchange).then(<a mono relevant to response>)
When I'm trying to test this using spock then method is not invoked from the stubbed Mono.
The filter itself:
@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*
});
}
This test passes despite 0 * _ in the end:
@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 * _
}
But in the code I invoke .then from the mono returned from .filter method.
Why isn't mono.then() taken into account? Of course when I try to test all the underlying logic - spock doesn't find interactions.
Losing hope to test the filter end-to-end I've extracted my runnable in a separate package private method and tested it without Monos and any other reactive things.
The code in my filter now looks like:
@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
return chain.filter(exchange)
.then(Mono.fromRunnable(refreshCookies(exchange)));
}
Runnable refreshCookies(ServerWebExchange exchange) {
return () -> {
//magic happens here ....
};
}
Any further clues and refactoring proposals are appreciated.