在空地图上调用每个失败

Calling every on empty map fails

在以下代码中,最后一个测试失败:

@Unroll
def "each #map"(Map map) {
    expect:
    map.each{ assert it.value != null }

    where:
    _ | map
    _ | [foo: 1, bar: 1]
    _ | [foo: 1, bar: null]
    _ | [:]
}

..消息:

Condition not satisfied:

map.each{ assert it.value != null }
|   |
[:] [:]

我想把一张空地图当作通行证。

我知道我可以使用 "every"。即

@Unroll
def "every #map"(Map map) {
    expect:
    map.every{ it.value != null }

    where:
    _ | map
    _ | [foo: 1, bar: 1]
    _ | [foo: 1, bar: null]
    _ | [:]
}

然而,失败消息的吸引力较低。与其列出坏值,不如列出整个集合。当唯一的值是 "foo" 和 "bar" 时,这还算不错,但在处理大型列表时很难阅读。

第 2 个案例:

Condition not satisfied:

it.value != null
|  |     |
|  null  false
bar=null

第 2 个案例:

Condition not satisfied:

map.every{ it.value != null }
|   |
|   false
[foo:1, bar:null]

有没有办法使用断言循环,同时将空映射视为通过?

您的测试失败是有原因的。只需检查以下表达式 [:].each { it.value != null } returns。它returns输入空图。在这种情况下 Groovy Truth 很简单 - 空映射的计算结果为 false 布尔值。

如果您想将 map.each {} 与显式断言一起使用,您可以在您的条件中添加一个小的 "exception" - 您可以明确期望空映射是有效的,对于所有剩余的情况,您检查非空映射内的所有值。

@Unroll
def "each #map"(Map map) {
    expect:
    map == [:] || map.each { assert it.value != null }

    where:
    _ | map
    _ | [foo: 1, bar: 1]
    _ | [foo: 1, bar: null]
    _ | [:]
}

如果您对看起来更具声明性并在断言中给出适当错误的东西感兴趣,您也可以尝试:

[a: null, b: 2, c: 3].findAll{ it.value == null }.isEmpty()

它以地图的形式为您提供了所有违规的 null 值(注意:输出来自 Groovy assert 而不是 Spock):

assert([a: null, b: 2, c: 3].findAll{ it.value == null }.isEmpty())
                             |                           |
                             ['a':null]                  false

        at x.run(x.groovy:1)

优势取决于您的用例:

  • 您看到 所有 个违规条目
  • 您会看到所有 的违规值