Search code examples
groovymockingspockjunit-rule

Spock test framework - how to parametrize a @Rule resource?


I am updating a Spock tests. There are few mocks and a @Rule resource:

AuthTokenService mockAuthTokenService = Mock()
ObjectMapper mockObjectMapper = Mock()

GeneralConfiguration conf = Mock();
def CLA_BASE_URL = "http://some-prefix/";

@Rule
ResourceTestRule resource = ResourceTestRule.builder()
    .addResource(new AuthResourceImpl(mockAuthTokenService, mockObjectMapper, conf))
    .build()

I need the resource to have different conf for two different tests. So I tried

def 'create auth token with configured URL prefix'() {
    setup:
    AuthTokenMetaData authTokenMetaData = buildAuthTokenMetaData()

    when:
    conf.getClaBaseUrl() >> CLA_BASE_URL
    ...

But that didn't work, because resource is created once. So I had to add another resource.

GeneralConfiguration conf2 = new GeneralConfiguration().setClaBaseUrl(CLA_BASE_URL);
@Rule
ResourceTestRule resource2 = ResourceTestRule.builder()
        .addResource(new AuthResourceImpl(mockAuthTokenService, mockObjectMapper, conf2))
        .build()

But that feels a bit weird, and from brief encounter with Spock, I believe it has some better approach to this.

How can I parametrize the ResourceTestRule?

It has to be a JUnit Rule because of the underlying implementation of ResourceTestRule.


Solution

  • As Leonard has mentioned, Spock is just a JUnit, it supports @Rule mechanism in the same sense as JUnit, as as such there is no special syntax for this.

    So if you need two different configurations, you should probably use two different rules definitions and depending on "groovy-ness" of the test come up with a solution that works for you best:

    Here is one example:

    class FirstConfigurationSpecification extends Specification {
       @Rule // config A
    }
    
    class SecondConfigurationSpecification extends Specification {
       @Rule // config B
    }
    
    // in tests
    class MyTestThatRequiresConfigurationA extends FirstConfigurationSpecification {}
    
    // in tests
    class MyTestThatRequiresConfigurationB extends SecondConfigurationSpecification {}