3

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"
        }
    }
th3morg
  • 4,321
  • 1
  • 32
  • 45
  • Can you past in your exact test code instead of the "//...". It might help determine what the problem is. – th3morg Oct 13 '14 at 18:18
  • @th3morg,that is something I felt confidential, but I am sure the above snippet will give such good idea. The issue is with the code inside the `Thread.start{}` – Suganthan Madhavan Pillai Oct 14 '14 at 04:25
  • I can't tell whether or not you've configured the test properly without seeing the entire test. You can even just provide the full test code and not the function that is proprietary. Also, were there any unmatched invocations? – th3morg Oct 14 '14 at 12:17
  • @th3morg, I don't the exact reason, but now the unit test is working, really don't know it is a hole in my project or bug in spock, from the very beginning this snippet shows some unusual behavior – Suganthan Madhavan Pillai Oct 14 '14 at 15:27
  • that's great. Ensure that it is not a false positive. Try to make the test fail on purpose to ensure it is actually testing your condition. Also, see my answer that I've finally posted below. Good luck and please accept my answer if it does help in the end! – th3morg Oct 14 '14 at 15:34

1 Answers1

4

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.

th3morg
  • 4,321
  • 1
  • 32
  • 45
  • thanks for your time, I didn't tested your code I got stuck in some other issue, also now I don't have a way to test this code, 'cause my existing code is working without `PollingConditions`, I don't the exact reason why my current code is working now, and why my previous code didn't work as expected.I want to make sure where things went wrong. Also I 'll try your code on possible chance. Thank u once again, +1 for your time – Suganthan Madhavan Pillai Oct 14 '14 at 17:42
  • @Suganthan We're you able to try my suggestion to determine if it worked for you and also assert that you didn't have a false positive test? – th3morg Oct 17 '14 at 02:33
  • Honestly specking I was just wondering, I really don't have a right answer for your question, sorry for that. Now I moved the code to production without `PollingConditions`, But I applied `PollingConditions` only because I had issue on handling `Thread`. Let me to reproduce such an error again or let it to occur again, 'cause the issue is not there for last 3 days after continous testing. Again thanks for your time – Suganthan Madhavan Pillai Oct 17 '14 at 06:35