Как я могу эффективно высмеивать свободный интерфейс со Spock mocks?

Я хотел бы высмеять некоторый свободный интерфейс с mock, который в основном является почтовым редактором:

this.builder()
            .from(from)
            .to(to)
            .cc(cc)
            .bcc(bcc)
            .template(templateId, templateParameter)
            .send();

Когда насмехается над этим с помощью Spock, для этого требуется много настроек, например:

def builder = Mock(Builder)
builder.from(_) >> builder
builder.to(_) >> builder 

и т.д.. Это становится еще более громоздким, если вы хотите проверить определенные взаимодействия с макетом, в зависимости от варианта использования. Поэтому у меня в основном были два вопроса:

  • Есть ли способ комбинировать макетные правила, чтобы я мог сделать общую единую настройку свободного интерфейса в методе, который я могу повторно использовать в каждом тестовом случае, а затем указать дополнительные правила для каждого тестового случая?
  • Есть ли способ указать насмешку свободного интерфейса с меньшим количеством кода, например. что-то вроде:

    def builder = Mock (Builder) builder./(from|to|cc|bcc|template)/(*) → builder

    или что-то эквивалентное Mockito Deep Stubs (см. http://docs.mockito.googlecode.com/hg/org/mockito/Mockito.html#RETURNS_DEEP_STUBS)

Ответ 1

Вы можете сделать что-то вроде этого:

def "stubbing and mocking a builder"() {
    def builder = Mock(Builder)
    // could also put this into a setup method
    builder./from|to|cc|bcc|template|send/(*_) >> builder

    when:
    // exercise code that uses builder

    then:
    // interactions in then-block override any other interactions
    // note that you have to repeat the stubbing
    1 * builder.to("fred") >> builder
}