gpt4 book ai didi

unit-testing - Spock如何处理Mocked对象的相等性

转载 作者:行者123 更新时间:2023-12-02 06:45:27 25 4
gpt4 key购买 nike

我正在测试使用库对象的 SortedSet 的类的行为(常规类不是接口(interface),因此我引入了 cglib-nodep)。当排序集有多个对象时,我需要测试类的行为。 Library 对象已通过以下方式进行模拟:

Library library = Mock()
Library library2 = Mock()

然后,我创建一个 TreeSet:

def libraries = [library, library2] as TreeSet

并调用被测系统方法:

sut.doStuff(libraries).

当我调试此测试时,我发现库是一个只有一个元素的 SortedSet。这似乎是 Spock 处理平等方式的结果,如下所示:

def "equality test"() {
expect:
library == library2
}

当我运行测试时通过了。有没有办法可以避免这种行为?

编辑:将=更改为==,因为我无法输入

最佳答案

做了一些研究。看一下以下一组测试(groovy 控制台脚本):

@Grab('org.spockframework:spock-core:0.7-groovy-2.0')
@Grab('cglib:cglib-nodep:3.1')

import spock.lang.*

class Test extends Specification {
def "not comparable mocks are not equal"() {
given:
def a1 = Mock(A)
def a2 = Mock(A)

expect:
a1.hashCode() != a2.hashCode()
!a1.equals(a2)
!(a1 == a2)
}

def "comparable mocks are not equal"() {
given:
def a1 = Mock(AC)
def a2 = Mock(AC)

expect:
a1.hashCode() != a2.hashCode()
!a1.equals(a2)
!(a1 == a2)
}

def "cannot create TreeSet when POJOs are not comparable"() {
given:
def a1 = Mock(A)
def a2 = Mock(A)

and:
a1.hashCode() != a2.hashCode()
!a1.equals(a2)
!(a1 == a2)

when:
new TreeSet([a1,a2])

then:
def e = thrown(ClassCastException)
e.message.endsWith('cannot be cast to java.lang.Comparable')
}

def "there's a problem with Comparable Mocks"() {
given:
def a1 = Mock(AC)
def a2 = Mock(AC)

and:
a1.hashCode() != a2.hashCode()
!a1.equals(a2)
!(a1 == a2)

when:
def s = new TreeSet([a1,a2])

then:
s.size() == 2
}

def "with HashSet it works as expected"() {
given:
def a1 = Mock(AC)
def a2 = Mock(AC)

and:
a1.hashCode() != a2.hashCode()
!a1.equals(a2)
!(a1 == a2)

when:
def s = new HashSet([a1,a2])

then:
s.size() == 2
}
}

class A {}

class AC implements Comparable {

int compareTo(Object o) {
1 //whatever value may be here, it's not called
}
}

通常,当对象实现 Comparable 接口(interface)时会出现问题。

  1. 第一个测试表明,同一对象的不同模拟具有不同的哈希码并且不相等。据我所知,这是预期的行为。
  2. 第二个测试检查相同的条件,但对象是Comparable这一事实。它失败。据我所知,这不是预期的行为。
  3. 第三个测试说明不可能使用不可比较的 POJO 创建 TreeSet。预期行为。
  4. 第四个测试说明了您提到的问题。使用两个 Comparable 模拟创建的 TreeSet 的大小预计为 2。它失败了,大小为 1。
  5. 第五个测试表明,使用 HashSet 时,满足第四个测试的条件。

IMO,这不是与 spock 相关的问题。 Spock 使用 cglib 作为模拟对象,这是应该寻找解释的地方。

编辑

如果为模拟对象覆盖 compareTo() 方法,则效果很好:

@Grab('org.spockframework:spock-core:0.7-groovy-2.0')
@Grab('cglib:cglib-nodep:3.1')

import spock.lang.*

class Test extends Specification {

def "there's a problem with Comparable Mocks"() {
given:
def a1 = Mock(AC) {
compareTo(_) >> 3145
}
def a2 = Mock(AC) {
compareTo(_) >> 3146
}

and:
a1.hashCode() != a2.hashCode()
!a1.equals(a2)
!(a1 == a2)

when:
def s = new TreeSet([a1,a2])

then:
s.size() == 2
}
}

class AC implements Comparable {

int compareTo(Object o) {
1 //whatever value may be here, it's not called
}
}

关于unit-testing - Spock如何处理Mocked对象的相等性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25552604/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com