【问题标题】:Spock mock won't return correct valueSpock 模拟不会返回正确的值
【发布时间】:2020-08-10 20:59:13
【问题描述】:

我已经为此奋斗了好几天。此模拟不会返回 SUCCESS (true): 1 * realtimeClient.send(_) >> SUCCESS。 从question 41841668 我发现我需要1 *,但我没有成功添加。我正在打印出realtimeClient.send() 结果的中间变量,它总是错误的。

RealtimeClient 和 QueueClient 是接口。我尝试使用具体类对RestfulEmailController 和 Spock 测试进行编码,但行为没有变化。我试过大的Boolean 而不是小的boolean,没有变化。文档说这应该可行,问题 41841668 说这应该可行(尽管示例代码不太完整)。

public static final boolean SUCCESS = true

def "test real time email success"() {
        given:
        RealtimeClient realtimeClient = Mock()
        QueueClient queueClient = Mock()

        1 * realtimeClient.send(_) >> SUCCESS

        RestfulEmailController restfulEmail = new RestfulEmailController(realtimeClient: realtimeClient, queueClient: queueClient)

        RestfulEmailContract email = new RestfulEmail(subject: "some subject")

        when:
        restfulEmail.sendRestfulEmail(email)

        then:
        1 * realtimeClient.send(_)
        0 * queueClient.send(_)
    }

控制器类被剥离成一个基本的例子看起来像

void sendRestfulEmail(@RequestBody RestfulEmail emailRequest) {
            boolean success = realtimeClient.send(emailRequest)
            System.out.println("success = " + success )
            if (!success ) {
                queueClient.send(emailRequest)
            }
    }

我做的任何事情都无法让系统打印“success = true”,而我对0 * queueCient.send(_)的期望失败了

【问题讨论】:

    标签: spock


    【解决方案1】:

    请参阅文档中的Combining Mocking and Stubbing,如果您模拟某些内容并需要返回一个值,则必须同时进行。因此,如果您将 given 块中的行 1 * realtimeClient.send(_) >> SUCCESS 合并到 then 块中,那么它会返回您所期望的值。

    def "test real time email success"() {
        given:
        RealtimeClient realtimeClient = Mock()
        QueueClient queueClient = Mock()
        RestfulEmailController restfulEmail = new RestfulEmailController(realtimeClient: realtimeClient, queueClient: queueClient)
        RestfulEmailContract email = new RestfulEmail(subject: "some subject")
    
        when:
        restfulEmail.sendRestfulEmail(email)
    
        then:
        1 * realtimeClient.send(_) >> SUCCESS
        0 * queueClient.send(_)
    }
    

    【讨论】:

    • 对于其他阅读本文的人,我想明确地说:OP 所犯的错误是then: 块中的冗余1 * realtimeClient.send(_)。它使先前正确的1 * realtimeClient.send(_) >> SUCCESS 无效,覆盖它。这个答案和OP提到的问题的答案都解释了正确的使用模式。 Spock 手册也是如此。
    • 虽然given 块中的第一个1 * realtimeClient.send(_) >> SUCCESS 可以工作,但把它放在那里是不好的做法。建议将验证交互放在 then 块中。
    • 我完全同意。我只是想为您的出色答案添加一个缺失的解释,因为即使在阅读了 Björn 的同样出色的答案之后,OP 也设法弄错了。
    猜你喜欢
    • 1970-01-01
    • 2023-03-26
    • 1970-01-01
    • 2021-09-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多