2015-11-19 6 views
3

Я следующие спецификации:Проверка вызова метода в конструкторе

@Grab('org.spockframework:spock-core:1.0-groovy-2.4') 
@Grab('cglib:cglib:3.1') 
@Grab('org.ow2.asm:asm-all:5.0.3') 

import spock.lang.* 

class Whatever extends Specification { 

    def "bind view to object in constructor"() { 
     given: 
     def view = Mock(View) 
     def binder = Mock(Binder) 

     when: 
     def holder = new Holder(binder, view) 

     then: 
     1 * binder.bind(holder, view) 
    } 
} 

class Binder { 
    def bind(Holder holder, View view) {} 
} 
class View {} 

class Holder { 
    Holder(Binder binder, View view) { 
     binder.bind(this, view) 
    } 
} 

который терпит неудачу с:

groovy.lang.MissingPropertyException: Нет такого свойства: держатель для класса: Независимо от

по следующей линии:

1 * binder.bind(holder, view) 

в then блок.

Я знаю, почему он терпит неудачу, поскольку then оценивается до when. Вопрос в том, как он может протестировать этот вызов конструктора binder.bind() без каких-либо сложных обходных решений?

ответ

2

Вы можете просто определить holder в given: блоке:

class Whatever extends Specification { 
    def "bind view to object in constructor"() { 
     given: 
     def view = Mock(View) 
     def binder = Mock(Binder) 
     def holder 

     when: 
     holder = new Holder(binder, view) 

     then: 
     1 * binder.bind(holder, view) 
    } 
} 

Однако это не удается:

Too few invocations for: 

1 * binder.bind(holder, view) (0 invocations) 

Unmatched invocations (ordered by similarity): 

1 * binder.bind([email protected], Mock for type 'View' named 'view') 

, потому что, когда взаимодействие проверяется holder еще не назначен. Таким образом, чтобы проверить взаимодействие, то лучше сделать:

class Whatever extends Specification { 
    def "bind view to object in constructor"() { 
     given: 
     def view = Mock(View) 
     def binder = Mock(Binder) 

     when: 
     new Holder(binder, view) 

     then: 
     1 * binder.bind(!null, view) // or 1 * binder(_ as Holder, view) 
    } 
} 

Если мы все еще хотим, чтобы проверить holder нам нужен closure to capture the arguments:

def "bind view to object in constructor"() { 
    given: 
    def view = Mock(View) 
    def binder = Mock(Binder) 
    def holder 
    def argHolder 

    when: 
    holder = new Holder(binder, view) 

    then: 
    1 * binder.bind(*_) >> { arguments ->    
     argHolder = arguments[0] 
     assert view == arguments[1] 
    } 
    assert argHolder == holder 
} 
+0

Спасибо, я знаю об этом решении. Это также является обходным решением. – Opal

+0

Просто добавил пример, показывающий, как захватывать аргументы с закрытием. – jalopaba

Смежные вопросы