kman
kman

Reputation: 330

How to test order of method calls and redirects in spock unit testing in grails?

I've been seeing some weird behavior with grails controller methods which has had me wanting to create a test case to see if I can reproduce this consistently. So,.. I'll explain the issue first to better understand my question.

I've had some weird behavior recently that when a grails method is called, it sometimes doesn't finish all the method implementation (basically all code goes to server calls) and does the redirect too early. I can see this by my service methods still running but the ui has already (sometimes also incorrectly) redirected wrongly. I've tried debugging through it, but it also leads me to the same places,.. I'll be in a service method but see the page already rendering on the ui. If I could get a good test case going, I feel this may be easier to debug.

Example controller code:

def blam() {
   Foo foo = Foo.get(params.id)
   String msg = service.method1(foo)
   service.method2(foo)
   service.doSomething(foo)
   redirect(action:"list", controller: "blam", params: [msg:msg, *:params])
}

Example test code: The problem below is that it doesn't actually test a call order at all, I want to test that it is calling the methods in the right order. I have found a couple examples say that you may call multiple then declarations but I dont see a difference if I move the methods around and re run the test.

def "test service call order and redirect"(){
   when:
   controller.actionMethod()

   then:
   service.method1(_) * 1
   service.method2(_) * 1
   service.doSomething(_) * 1

   then:
   response.redirectedUrl == "bam/list"   
}

Any help with how to test this scenario would be greatly appreciated! Also I know it's not the main question but ideas on the redirect are also welcome! (or should I create a different question?)

Cheers!

Upvotes: 4

Views: 2575

Answers (1)

zoran119
zoran119

Reputation: 11327

Use multiple then blocks:

then:
   service.method1(_) * 1

then:
   service.method2(_) * 1

then:
   service.doSomething(_) * 1

The order should be respected then (see http://spock-framework.readthedocs.org/en/latest/interaction_based_testing.html#invocation-order)

Upvotes: 6

Related Questions