Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I efficiently mock a fluent interface with Spock mocks?

I'd like to mock some fluent interface with mock, which is basically a mail builder:

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

When mocking this with Spock, this needs a lot of setup like this:

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

etc. It becomes even more cumbersome when you want to test certain interactions with the mock, depending on the use case. So I basically got two questions here:

  1. Is there a way to combine mock rules, so that I could do a general one time setup of the fluent interface in a method that I can reuse on every test case and then specify additional rules per test-case?
  2. Is there a way to specify the mocking of a fluent interface with less code, e.g. something like:

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

    or something equivalent to Mockito's Deep Stubs (see http://docs.mockito.googlecode.com/hg/org/mockito/Mockito.html#RETURNS_DEEP_STUBS)

like image 393
Jan Thomä Avatar asked May 27 '13 11:05

Jan Thomä


1 Answers

You can do something like this:

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
}
like image 122
Peter Niederwieser Avatar answered Sep 20 '22 16:09

Peter Niederwieser