代码之家  ›  专栏  ›  技术社区  ›  Anton Hlinisty

用spock对spring云网关过滤器进行单元测试

  •  0
  • Anton Hlinisty  · 技术社区  · 5 年前

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

    当我试着用斯波克测试的时候 然后

    过滤器本身:

    @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 * _
    }
    

    但在我调用的代码中 。然后 从单声道返回 .过滤器

    为什么不 单声道。然后() 考虑到了吗?当然,当我尝试测试所有底层逻辑时,spock找不到交互。

    0 回复  |  直到 5 年前
        1
  •  0
  •   Mark Bramnik    5 年前

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

    (我相信这是你问题的答案),所以测试并没有真正检查过滤器,它只检查是否有一个调用 .

    此外,Spock除了mock之外还支持stub,与许多其他框架不同的是,它们之间有一个区别:

    通常,如果希望模拟某些交互并将测试基于围绕此交互管理的协议,则可以使用mock,在其他情况下,最好使用stub。

        2
  •  0
  •   Anton Hlinisty    5 年前

    失去了端到端测试过滤器的希望,我已经在一个单独的包私有方法中提取了我的runnable,并在没有Monos和其他任何反应的情况下测试了它。

    我的过滤器中的代码现在看起来像:

    @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 ....
        };
    }
    

    任何进一步的线索和重构建议都值得赞赏。