【问题标题】:Define a Lambda function as Argument Constraint in Spock在 Spock 中将 Lambda 函数定义为参数约束
【发布时间】:2018-09-28 11:27:38
【问题描述】:

我想用单元测试覆盖一段代码

public List<Product> fetchProducts() {
   ...
   String userId = anotherObj.getId()
   return caller.call(client -> client.getProducts(userId));
}

注意:我无法更改该代码

现在,这是使用通配符工作的单元测试(省略了所有不相关的内容):

def anotherObj = Mock( ... )
def caller = Mock( ... )

...

when:
  subject.fetchProducts()

then:
  1 * anotherObj.getId() >> USER_ID
and:
  1 * caller.call(_) >> mockedApiResponse

问题

我想检查函数 call 是否实际上是使用接收参数的函数调用并使用正确的参数调用该参数

伪代码

then:
  1 * anotherObj.getId() >> USER_ID
and:
  1 * caller.call( { it(obj -> obj.getProducts(USER_ID)) } ) >> mockedApiResponse

【问题讨论】:

    标签: java groovy lambda mocking spock


    【解决方案1】:

    如果有人遇到这个;

    解决方案是为callermock 定义一个行为:当caller 被调用时带有一个参数,那么

    • 首先,该参数是Function
    • 模拟实际上是用一个参数调用它
    • 该参数是一个 groovy 模拟,因此我们稍后将能够对其创建断言。

    代码:

    def anotherObj = Mock( ... )
    def caller = Mock( ... )
    def client = Mock( ... )
    
    ...
    
    when:
      def response = subject.fetchProducts()
    
    then:
      1 * anotherObj.getId() >> USER_ID
    and:
      1 * caller.call(_) >> { Function lambda ->
          lambda.apply(client)
          return apiResponse
      }
    and:
      1 * client.getProducts(USER_ID)
    and:
      response == ...
    

    【讨论】:

    • 从技术上讲,答案是正确的。但是您的测试也涵盖了代码,而无需您验证client.getProducts() 上的交互。对我来说,这看起来像是过度规范。为什么你甚至关心内部实现而不仅仅是测试该方法是否真正做正确的事情?如果你曾经重构,你需要调整测试,即使方法仍然做同样的事情。我认为没有理由验证在方法内部调用了特定的 getter。我假设客户端类有自己的测试,不是吗?
    • 其他:根据您的测试代码,在您的最终and: response == ... 中,断言只能是response == apiResponse,即您实际上是在验证使用模拟调用者参数化的主题实际上返回了您的存根结果说应该。这意味着您只是在这种情况下测试您的模拟。也许让客户成为 Spock 间谍而不是模拟者会更有意义。但这取决于您要测试的内容。显然,检查模拟是否返回模拟结果是没有意义的。
    • 如您所说,取决于您要测试的内容。这是非常人为的,这里唯一的改进是我可以在getProducts()client.getProducts(USER_ID) 断言调用的参数(如果用不同的参数调用,这个测试会告诉我,之前没有发生过通配符)。无论如何,将这个问题保留在stackoverflow,因为它可能对另一个人有用:)
    猜你喜欢
    • 2010-12-03
    • 1970-01-01
    • 2020-03-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多