加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 大数据 > 正文

单元测试 – Spock如何处理Mocked对象的相等性

发布时间:2020-12-14 16:24:11 所属栏目:大数据 来源:网络整理
导读:我正在测试使用Library对象的SortedSet的类的行为(常规类不是接口,因此我引入了cglib-nodep).当排序集有多个对象时,我需要测试类的行为. Library对象已经以这种方式被模拟: Library library = Mock()Library library2 = Mock() 然后,我创建一个TreeSet: de
我正在测试使用Library对象的SortedSet的类的行为(常规类不是接口,因此我引入了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接口时会出现问题.

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

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

编辑

如果compareTo()方法被重写为mock对象,它可以正常工作:

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

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读