2017-10-19 117 views
2

我有从斯波克Groovy中嘲笑接口返回所需的对象列表的问题:如何在常规斯波克测试模拟返回列表

public interface SomeRepository { 
    List<SomeObject> getAll(); 
} 

所以我想嘲弄,在类:

@CompileStatic 
class SomeProcessor { 
    private final SomeRepository repository 

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

    List<SomeObject> 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) 
    } 
} 

当我尝试运行测试,我得到一个断言错误:

junit.framework.AssertionFailedError: Expected :[[email protected], [email protected]] Actual :null

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

+0

'repository.all >> expected'看起来像去除我。尝试用'repository.all = new ArrayList(预期)'替换它' – injecteer

+0

我测试了你的代码1:1,我改变的唯一的东西是'Object'而不是'SomeObject',它工作得很好,就像你期望的那样工作。我尝试了Spock 1.0-groovy-2.4和1.1-groovy-2.4,两者都工作得很好。 – Vampire

+0

顺便说一句,这是不适合你的或者短暂的PoC,试图反映你的问题的确切代码?也许你面临类似的问题 - https://github.com/kiview/spring-spock-mock-beans-demo/issues/1? –

回答

3

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

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 
} 

你也不必使用JUnit的assertEquals - Groovy的操作让您既能对象与==运营商进行比较。

我已经在简单的基于Spock的应用程序中检查了您的示例,它工作正常。我用Spock 0.7-groovy-2.01.0-groovy-2.41.2-groovy-2.4-SNAPSHOT对它进行了测试,与所有Spock版本一起工作。无论如何,我在过去遇到过类似的问题,因为交互检查在这些情况下做了诡计。希望能帮助到你。

+0

感谢您提供有关交互检查的提示 –

0

根据白盒测试更好地测试完全相同的实施。 processor.all按原样返回repository.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()我们验证了相同的标号。

因为它不是什么列表,它可以只是空的。