Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

how to call a method or closure in a where clause in a spock test

I'm working with Spock tests atm and I wonder if anything like this is even possbile. My approaches don't work and I wonder if anyone of you had similiar intentions and found a way.

I want to call a method or a closure which must only be called for each respective where-clause in order to setup some things. I can not just call all of these methods as it would ruin my test. The only way I found so far is to check what the current state is and call the method accordingly in an if statement like: if(state==SomeStateEnum.FIRST_STATE){somePrivateMethodFromSpec()} but I wonder if it couldn't be done in a better way. I hope my intentions are clear (sorry, I'm no native speaker) Below is some example code which may be a bit better to understand of what I want to do. Thank you in advance.

def 'is this even possible?'() {
    when:
    def resultState = service.someServiceMethod(param)

    then:
    resultState == state

    where:
    state                       | param     | method
    SomeStateEnum.FIRST_STATE   | 'param1'  | somePrivateMethodFromSpec()
    SomeStateEnum.SECOND_STATE  | 'param2'  | someOtherPrivateMethodFromSpec()
}

private def somePrivateMethodFromSpec() {
    someServiceMock.demand.AAA() {}
}

private def someOtherPrivateMethodFromSpec() {
    someServiceMock.demand.BBB() {}
}

def 'or maybe something like this?'() {
    when:
    closure.call()
    def resultState = service.someServiceMethod(param)

    then:
    resultState == state

    where:
    state                       | param     | closure
    SomeStateEnum.FIRST_STATE   | 'param1'  | {println '1'}
    SomeStateEnum.SECOND_STATE  | 'param2'  | {println '2'}
}

The solution is:

def 'this will work'() {
    "$someOtherPrivateMethodFromSpec"()
    "$somePrivateMethodFromSpec"()
    def resultState = service.someServiceMethod(param)

    then:
    resultState == state

    where:
    state                       | param     | method
    SomeStateEnum.FIRST_STATE   | 'param1'  | "somePrivateMethodFromSpec"
    SomeStateEnum.SECOND_STATE  | 'param2'  | "someOtherPrivateMethodFromSpec"
}

private def somePrivateMethodFromSpec() {
    someServiceMock.demand.AAA() {}
}

private def someOtherPrivateMethodFromSpec() {
    someServiceMock.demand.BBB() {}
}
like image 785
IwantToKnow Avatar asked Jan 14 '14 12:01

IwantToKnow


People also ask

What is Spock testing framework?

Similar to most of the unit testing frameworks, Spock also provides setup and cleanup methods for executing special logic/tasks at specific lifecycle events of test execution. These methods are called once for each Spec execution and are called before and after the test execution respectively.

Can Spock verify the Order in which mock methods are called?

And in addition to verifying the mock method calls we specify, we can verify no other extra methods are called on our mock objects: Spock also provides the ability to verify the order in which mock methods are called by specifying the order in multiple ‘then’ blocks:

What is the best way to do unit testing with Spock?

Spock makes it easy by combining these features as a part of the framework itself with a more readable groovy syntax along with the lesser boilerplate code. Mocks, Stubs, and Spies are used extensively in unit testing for increasing coverage and testing or validating the core business logic of the application under test.

How does Spock understand JUnit rules?

Spock understands @org.junit.Rule annotations on non- @Shared instance fields. The according rules are run at the iteration interception point in the Spock lifecycle. This means that the rules before-actions are done before the execution of setup methods and the after-actions are done after the execution of cleanup methods.


1 Answers

In order to call the closure way you just need to add more parenthesis around the closure in the where clause.

E.g. ({ println("1") })

Or as the full spec.

def 'or maybe something like this?'() {
    when:
    closure.call()
    def resultState = service.someServiceMethod(param)

    then:
    resultState == state

    where:
    state                       | param     | closure
    SomeStateEnum.FIRST_STATE   | 'param1'  | ({println '1'}) 
    SomeStateEnum.SECOND_STATE  | 'param2'  | ({println '2'})
}
like image 90
Chris Balogh Avatar answered Nov 05 '22 16:11

Chris Balogh