liuyingyyll / spock

Automatically exported from code.google.com/p/spock
0 stars 0 forks source link

States for interaction #130

Open GoogleCodeExporter opened 8 years ago

GoogleCodeExporter commented 8 years ago
Need some way of ordering interactions not based in strict order of declaration 
of 'then' blocks. An ordering based on 'states' is needed in some scenarios. 

This mechanism is very useful to test interaction generated by a stateful 
object.

Of course perhaps it is yet implemented in Spock but not documented. If this is 
the case some samples would be useful.

Original issue reported on code.google.com by eamodeor...@gmail.com on 7 Oct 2010 at 10:51

GoogleCodeExporter commented 8 years ago
Spock doesn't support this feature at the moment. How often do you have a need 
for it? Do you currently use JMock for this, and have you considered using 
JMock together with Spock for when you need this feature?

Original comment by pnied...@gmail.com on 7 Oct 2010 at 8:23

GoogleCodeExporter commented 8 years ago
I need this feature in about 15% of my tests.
As I've worked with jmock several years it won't be a problem to mix it with 
spock.
But I'd prefer to have support for this feature in spock to use a single test 
framework
 I like very much spock but I think this feature is important.

Original comment by eamodeor...@gmail.com on 8 Oct 2010 at 6:59

GoogleCodeExporter commented 8 years ago
I think that using jmock for some tests scenarios and spock for others would be 
confusing and difficult to understand. That's why I'd only consider this 
solution as a last ressort.

There is no need to implement "states" in the same way as JMock but only to 
provide an equivalent functionality.

I've been thinking about implementing "states" using "spock's way". Perhaps a 
good approach is not to implement "states", but to introduce preconditions and 
actions to interactions. This can implement the "states" feature and give more 
flexibility and power to spock's interaction, which is good for unforeseen 
future needs. So, using this hypothetic "preconditions" and "actions", we can 
implement "states", with some code like the following:
then: 
  interaction {
    def state="some state";
    [state == "some state"] 1 * someObject.someMethod(paramMatcher) { actualParamValue -> state = "other state"; return "mocked method return value"; }
    [state == "other state" ] 1 * otherObject.otherMethod(_) >> returnValue
  }
The optional "[ some assert ]" block could act as a precondition that must be 
true to accept the interaction. 
The "closure" can define an action, which is executed if expectations are met 
for the interaction. The action can perform any code and optionally return a 
value as result for the mocked method. In fact you can now use a closure to 
define a parameter matcher, so it makes sense to use it to define an action.

Original comment by eamodeor...@gmail.com on 8 Oct 2010 at 12:21

GoogleCodeExporter commented 8 years ago
Thanks for the proposal, we'll consider it. By the way, actions are already 
supported:

1 * foo.bar(baz) >> { arg -> doSomething(arg) }

Original comment by pnied...@gmail.com on 8 Oct 2010 at 12:30

GoogleCodeExporter commented 8 years ago
Ok, thank you. Didn't know that actions were implemented. So, in fact, there is 
only need to implement "preconditions" to have "states".

Original comment by eamodeor...@gmail.com on 8 Oct 2010 at 12:34

GoogleCodeExporter commented 8 years ago
I'm trying to come up with a syntax for "preconditions". Since we already have 
"interaction { ... }", how do you like the following?

def state = "on" // can use any variable

interaction(state: "on") {
  device.powerOff() >> { state = "off" }
  ...
}                                      

interaction(state: "off") {
  device.powerOn() >> { state = "on" }
  ...
}     

Original comment by pnied...@gmail.com on 3 Nov 2010 at 3:13

GoogleCodeExporter commented 8 years ago
Nice ! I like it.

Original comment by eamodeor...@gmail.com on 3 Nov 2010 at 6:41