Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

grails unit test + Thread

Tags:

grails

spock

I having a grails function, where I am using a separate Thread:

def testFunction() {
   //.....
   Thread.start() {
     testService.somefunction()
   }
   //...

}

In the unit test, I'm mocking the service function like this:

def "test testfunction" {
   //...
   1 * testService.somefunction(_)
   //..
}

However, I get the unmatched invocations error, because Spock didn't detect that the method was executed on the separate thread.

1 * testService.somefunction(_)   (0 invocations)
Unmatched invocations (ordered by similarity):

I tried using this http://spock-framework.readthedocs.org/en/latest/new_and_noteworthy.html#polling-conditions, but didn't have any success.

Updated to include a code sample:

void "test without errors"() {

        def conditions = new PollingConditions(timeout: 15)

        def cmdList = new ArrayList<CommandClass>()
        parseService.parseFile(file, _) >> commandList
        nextService.create(_) >>  commandList
        controller.controllerService = nextService
        controller.controllerParseService = parseService

        when:
        controller.testFunction()

        then:
        conditions.eventually {
            assert response.contentAsString == "SUCCESS"
        }
    }
like image 635
Suganthan Madhavan Pillai Avatar asked May 16 '26 01:05

Suganthan Madhavan Pillai


1 Answers

Per your original code, you unfortunately cannot test number of invocations in the traditional way because within a closure you have to you assert the condition because the closure isn't in the context of the spock executor. I would recommend something like this, which has worked for me:

def "test concurrency"(){
        given:
            def conditions = new PollingConditions(timeout: 15)
            MyService service = new MyService()
            SomeService someService = Mock()
            service.validationService = someService
            int numInvocations = 0
            someService.methodExecutedInThread(_) >> {
                numInvocations++
                return null
            }
        when:
            int i = 0
            service.aMethod()
        then:
            conditions.eventually {
                println "checked ${i}" // <--- you should see this checking repeatedly until the condition is met 
                i++
                assert numInvocations == 1
            }
    }

Given the method in "service":

  public void aMethod(){
        Thread.start{
            sleep(5000)
            println "awake!"
            someService.methodExecutedInThread("some param")
        }
    }

Based on your updated code example:

Unfortunately, you are trying to test a response and this unfortunately won't work if you are sending the response from within a thread. Without seeing what the actual function looks like, I can't say more. However, what I've placed above should help answer your original question.

like image 67
th3morg Avatar answered May 17 '26 17:05

th3morg