Java 如何在groovy spock测试中返回模拟列表

Java 如何在groovy spock测试中返回模拟列表,java,unit-testing,groovy,junit,spock,Java,Unit Testing,Groovy,Junit,Spock,我在从Spock Groovy mocked interface返回所需对象列表时遇到问题: public interface SomeRepository { List<SomeObject> getAll(); } 公共接口存储库{ List getAll(); } 所以我想在课堂上嘲弄一下: @CompileStatic class SomeProcessor { private final SomeRepository repository So

我在从Spock Groovy mocked interface返回所需对象列表时遇到问题:

public interface SomeRepository {
    List<SomeObject> getAll();
}
公共接口存储库{
List getAll();
}
所以我想在课堂上嘲弄一下:

@CompileStatic
class SomeProcessor {
    private final SomeRepository repository

    SomeProcessor(SomeRepository repository) {
        this.repository = repository
    }

    List<SomeObject> getAll() {
        return repository.all
    }
}
@CompileStatic
类处理器{
私有最终存储库
SomeProcessor(SomeRepository存储库){
this.repository=存储库
}
列表getAll(){
return repository.all
}
}
我有一个测试:

class SomeProcessorSpec extends Specification {
    private final SomeRepository repository = Mock(SomeRepository)

    @Subject private final SomeProcessor processor = new SomeProcessor(repository)

    def 'should collect items from repository'() {
        given:
            List<SomeObject> expected = [new SomeObject(), new SomeObject()]
            repository.all >> expected

        when:
            List<SomeObject> actual = processor.all

        then:
            assertEquals(expected, actual)
    }
}
class SomeProcessorSpec扩展了规范{
私有最终SomeRepository repository=Mock(SomeRepository)
@Subject private final SomeProcessor processor=新SomeProcessor(存储库)
def“应从存储库中收集项目”(){
鉴于:
所需列表=[new SomeObject(),new SomeObject()]
repository.all>>预期
什么时候:
List实际值=processor.all
然后:
资产质量(预期、实际)
}
}
当我尝试运行该测试时,我得到一个断言错误:

junit.framework.AssertionFailedError: 预期:[com.example。SomeObject@1fa268de,com.example。SomeOjbect@4f6ee6e4] 实际值:空


这意味着它从
repository.all
方法返回
null
而不是我期望的列表,这让我很困惑。问题是:在使用spock和groovy进行测试时,如何实际从模拟实例返回列表?

您可以尝试将存根部分移动到交互检查阶段,例如

def 'should collect items from repository'() {
    given:
        List<SomeObject> expected = [new SomeObject(), new SomeObject()]

    when:
        List<SomeObject> actual = processor.all

    then:
        1 * repository.all >> expected

    and:
        expected == actual
}
def'应该从存储库中收集项目'(){
鉴于:
所需列表=[new SomeObject(),new SomeObject()]
什么时候:
List实际值=processor.all
然后:
1*repository.all>>应为
以及:
预期==实际
}
另外,您不必使用JUnit的
assertEquals
——Groovy允许您使用
=
操作符比较这两个对象


我已经在简单的基于Spock的应用程序中检查了您的示例,它运行良好。我用Spock
0.7-groovy-2.0
1.0-groovy-2.4
1.2-groovy-2.4-SNAPSHOT
对它进行了测试,并使用了所有Spock版本。无论如何,我在过去也遇到过一些类似的问题,在这些情况下,交互检查起到了关键作用。希望有帮助。

根据白盒测试,更好地测试完全相同的实现
processor.all
返回
存储库的结果。all
按原样返回。所以,最好测试一下这个事实

根据Szymon Stepniak提供的正确代码,测试可简化为:

def 'should collect items from repository'() {
    given:
        def expected = []

    when:
        def actual = processor.all

    then:
        1 * repository.all >> expected

    and: 'make sure we got the same expected list instance'
        actual.is(expected)
}
其中,通过
.is()
我们验证相同的引用


因此,无论列表中有什么内容,它都可以是空的。

repository.all>>预期的
在我看来就像删除一样。尝试将其替换为
repository.all=new ArrayList(预期)
我以1:1测试了您的代码,唯一更改的是
Object
而不是
SomeObject
,它工作得很好,与您预期的工作方式完全相同。我试过Spock 1.0-groovy-2.4和1.1-groovy-2.4,两者都很好。顺便问一句,这是不适合您的代码还是试图反映您问题的短PoC?也许你面临着和那个类似的问题-?